brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · e996690 Raw
370 lines · cpp
1// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \2// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: true}}" -- -fno-delayed-template-parsing3// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \4// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: true}}" -- -fno-delayed-template-parsing5// RUN: %check_clang_tidy -check-suffix=,NOSUBEXPR -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \6// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: false, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: true}}" -- -fno-delayed-template-parsing7// RUN: %check_clang_tidy -check-suffix=,UNNAMED -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \8// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: false, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: true}}" -- -fno-delayed-template-parsing9// RUN: %check_clang_tidy -check-suffix=,NONDEDUCED -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \10// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: false}}" -- -fno-delayed-template-parsing11 12// NOLINTBEGIN13namespace std {14template <typename>15struct remove_reference;16 17template <typename _Tp> struct remove_reference { typedef _Tp type; };18template <typename _Tp> struct remove_reference<_Tp&> { typedef _Tp type; };19template <typename _Tp> struct remove_reference<_Tp&&> { typedef _Tp type; };20 21template <typename _Tp>22constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;23 24template <typename _Tp>25constexpr _Tp &&26forward(typename remove_reference<_Tp>::type &__t) noexcept;27 28}29// NOLINTEND30 31struct Obj {32  Obj();33  Obj(const Obj&);34  Obj& operator=(const Obj&);35  Obj(Obj&&);36  Obj& operator=(Obj&&);37  void member() const;38};39 40void consumes_object(Obj);41 42void never_moves_param(Obj&& o) {43  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]44  o.member();45}46 47void just_a_declaration(Obj&& o);48 49void copies_object(Obj&& o) {50  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]51  Obj copy = o;52}53 54template <typename T>55void never_moves_param_template(Obj&& o, T t) {56  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]57  o.member();58}59 60void never_moves_params(Obj&& o1, Obj&& o2) {61  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]62  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]63}64 65void never_moves_some_params(Obj&& o1, Obj&& o2) {66  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]67 68  Obj other{std::move(o2)};69}70 71void never_moves_unnamed(Obj&&) {}72// CHECK-MESSAGES-UNNAMED: :[[@LINE-1]]:31: warning: rvalue reference parameter '' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]73 74void never_moves_mixed(Obj o1, Obj&& o2) {75  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]76}77 78void lambda_captures_parameter_as_value(Obj&& o) {79  auto f = [o]() {80    consumes_object(std::move(o));81  };82  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]83}84 85void lambda_captures_parameter_as_value_nested(Obj&& o) {86  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]87  auto f = [&o]() {88    auto f_nested = [o]() {89      consumes_object(std::move(o));90    };91  };92  auto f2 = [o]() {93    auto f_nested = [&o]() {94      consumes_object(std::move(o));95    };96  };97  auto f3 = [o]() {98    auto f_nested = [&o]() {99      auto f_nested_inner = [&o]() {100        consumes_object(std::move(o));101      };102    };103  };104  auto f4 = [&o]() {105    auto f_nested = [&o]() {106      auto f_nested_inner = [o]() {107        consumes_object(std::move(o));108      };109    };110  };111}112 113void misc_lambda_checks() {114  auto never_moves = [](Obj&& o1) {115    Obj other{o1};116  };117  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]118 119#if __cplusplus >= 201402L120  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {121    Obj other{o1};122  };123  // CHECK-MESSAGES-CXX14: :[[@LINE-3]]:47: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]124#endif125}126 127template <typename T>128void forwarding_ref(T&& t) {129  t.member();130}131 132template <typename T>133void forwarding_ref_forwarded(T&& t) {134  forwarding_ref(std::forward<T>(t));135}136 137template <typename... Ts>138void type_pack(Ts&&... ts) {139  (forwarding_ref(std::forward<Ts>(ts)), ...);140}141 142void call_forwarding_functions() {143  Obj o;144 145  forwarding_ref(Obj{});146  type_pack(Obj{});147  type_pack(Obj{}, o);148  type_pack(Obj{}, Obj{});149}150 151void moves_parameter(Obj&& o) {152  Obj moved = std::move(o);153}154 155void moves_parameter_extra_parens(Obj&& o) {156  Obj moved = std::move((o));157}158 159void does_not_move_in_evaluated(Obj&& o) {160  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]161  using result_t = decltype(std::move(o));162  unsigned size = sizeof(std::move(o));163  Obj moved = o;164}165 166template <typename T1, typename T2>167struct mypair {168  T1 first;169  T2 second;170};171 172void moves_member_of_parameter(mypair<Obj, Obj>&& pair) {173  // CHECK-MESSAGES-NOSUBEXPR: :[[@LINE-1]]:51: warning: rvalue reference parameter 'pair' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]174  Obj a = std::move(pair.first);175  Obj b = std::move(pair.second);176}177 178template <typename T>179struct myoptional {180  T& operator*() &;181  T&& operator*() &&;182};183 184void moves_deref_optional(myoptional<Obj>&& opt) {185  // CHECK-MESSAGES-NOSUBEXPR: :[[@LINE-1]]:45: warning: rvalue reference parameter 'opt' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]186  Obj other = std::move(*opt);187}188 189void moves_optional_then_deref_resulting_rvalue(myoptional<Obj>&& opt) {190  Obj other = *std::move(opt);191}192 193void pass_by_lvalue_reference(Obj& o) {194  o.member();195}196 197void pass_by_value(Obj o) {198  o.member();199}200 201void pass_by_const_lvalue_reference(const Obj& o) {202  o.member();203}204 205void pass_by_const_lvalue_reference(const Obj&& o) {206  o.member();207}208 209void lambda_captures_parameter_as_reference(Obj&& o) {210  auto f = [&o]() {211    consumes_object(std::move(o));212  };213}214 215void lambda_captures_parameter_as_reference_nested(Obj&& o) {216  auto f = [&o]() {217    auto f_nested = [&o]() {218      auto f_nested2 = [&o]() {219        consumes_object(std::move(o));220      };221    };222  };223}224 225#if __cplusplus >= 201402L226void lambda_captures_parameter_generalized(Obj&& o) {227  auto f = [o = std::move(o)]() {228    consumes_object(std::move(o));229  };230}231#endif232 233void negative_lambda_checks() {234  auto never_moves_nested = [](Obj&& o1) {235    auto nested = [&]() {236      Obj other{std::move(o1)};237    };238  };239 240#if __cplusplus >= 201402L241  auto auto_lvalue_ref_param = [](auto& o1) {242    Obj other{o1};243  };244 245  auto auto_forwarding_ref_param = [](auto&& o1) {246    Obj other{o1};247  };248 249  auto does_move_auto_rvalue_ref_param = [](auto&& o1) {250    Obj other{std::forward(o1)};251  };252#endif253 254  auto does_move = [](Obj&& o1) {255    Obj other{std::move(o1)};256  };257 258  auto not_rvalue_ref = [](Obj& o1) {259    Obj other{std::move(o1)};260  };261 262  Obj local;263  auto captures = [local]() { };264}265 266struct AClass {267  void member_with_lambda_no_move(Obj&& o) {268    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]269    auto captures_this = [=, this]() {270      Obj other = std::move(o);271    };272  }273  void member_with_lambda_that_moves(Obj&& o) {274    auto captures_this = [&, this]() {275      Obj other = std::move(o);276    };277  }278};279 280void useless_move(Obj&& o) {281  // FIXME - The object is not actually moved from - this should probably be282  // flagged by *some* check. Which one?283  std::move(o);284}285 286template <typename>287class TemplatedClass;288 289template <typename T>290void unresolved_lookup(TemplatedClass<T>&& o) {291  TemplatedClass<T> moved = std::move(o);292}293 294struct DefinesMove {295  DefinesMove(DefinesMove&& rhs) : o(std::move(rhs.o)) { }296  DefinesMove& operator=(DefinesMove&& rhs) {297    if (this != &rhs) {298      o = std::move(rhs.o);299    }300    return *this;301  }302  Obj o;303};304 305struct DeclaresMove {306  DeclaresMove(DeclaresMove&& rhs);307  DeclaresMove& operator=(DeclaresMove&& rhs);308};309 310struct AnotherObj {311  AnotherObj(Obj&& o) : o(std::move(o)) {}312  AnotherObj(Obj&& o, int) { o = std::move(o); }313  Obj o;314};315 316template <class T>317struct AClassTemplate {318  AClassTemplate(T&& t) {}319  // CHECK-MESSAGES-NONDEDUCED: :[[@LINE-1]]:22: warning: rvalue reference parameter 't' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]320 321  void moves(T&& t) {322    T other = std::move(t);323  }324  void never_moves(T&& t) {}325  // CHECK-MESSAGES-NONDEDUCED: :[[@LINE-1]]:24: warning: rvalue reference parameter 't' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]326};327 328void instantiate_a_class_template() {329  Obj o;330  AClassTemplate<Obj> withObj{std::move(o)};331  withObj.never_moves(std::move(o));332 333  AClassTemplate<Obj&> withObjRef(o);334  withObjRef.never_moves(o);335}336 337namespace gh68209 {338  void f1([[maybe_unused]] int&& x) {}339 340  void f2(__attribute__((unused)) int&& x) {}341 342  void f3(int&& x) {}343  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: rvalue reference parameter 'x' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]344 345  template <typename T>346  void f4([[maybe_unused]] T&& x) {}347 348  template <typename T>349  void f5(__attribute((unused)) T&& x) {}350 351  template<typename T>352  void f6(T&& x) {}353 354  void f7([[maybe_unused]] int&& x) { x += 1; }355  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: rvalue reference parameter 'x' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]356 357  void f8(__attribute__((unused)) int&& x) { x += 1; }358  // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: rvalue reference parameter 'x' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]359} // namespace gh68209360 361namespace gh69412 {362  struct S363  {364      S(const int&);365      S(int&&) = delete;366 367      void foo(int&&) = delete;368  };369} // namespace gh69412370