1 // RUN: %check_clang_tidy %s performance-move-const-arg %t \ 2 // RUN: -config='{CheckOptions: \ 3 // RUN: [{key: performance-move-const-arg.CheckTriviallyCopyableMove, value: 0}]}' 4 5 namespace std { 6 7 template <typename> struct remove_reference; 8 template <typename _Tp> struct remove_reference { typedef _Tp type; }; 9 template <typename _Tp> struct remove_reference<_Tp &> { typedef _Tp type; }; 10 template <typename _Tp> struct remove_reference<_Tp &&> { typedef _Tp type; }; 11 12 template <typename _Tp> move(_Tp && __t)13constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) { 14 return static_cast<typename std::remove_reference<_Tp>::type &&>(__t); 15 } 16 17 template <typename _Tp> 18 constexpr _Tp && forward(typename remove_reference<_Tp>::type & __t)19forward(typename remove_reference<_Tp>::type &__t) noexcept { 20 return static_cast<_Tp &&>(__t); 21 } 22 23 } // namespace std 24 25 class NoMoveSemantics { 26 public: 27 NoMoveSemantics(); 28 NoMoveSemantics(const NoMoveSemantics &); 29 30 NoMoveSemantics &operator=(const NoMoveSemantics &); 31 }; 32 33 void callByConstRef(const NoMoveSemantics &); 34 void callByConstRef(int i, const NoMoveSemantics &); 35 moveToConstReferencePositives()36void moveToConstReferencePositives() { 37 NoMoveSemantics obj; 38 39 // Basic case. It is here just to have a single "detected and fixed" case. 40 callByConstRef(std::move(obj)); 41 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as a const reference argument; no move will actually happen [performance-move-const-arg] 42 // CHECK-FIXES: callByConstRef(obj); 43 } 44 45 struct TriviallyCopyable { 46 int i; 47 }; 48 f(TriviallyCopyable)49void f(TriviallyCopyable) {} 50 g()51void g() { 52 TriviallyCopyable obj; 53 f(std::move(obj)); 54 } 55 56 class MoveSemantics { 57 public: 58 MoveSemantics(); 59 MoveSemantics(MoveSemantics &&); 60 61 MoveSemantics &operator=(MoveSemantics &&); 62 }; 63 64 void fmovable(MoveSemantics); 65 lambda1()66void lambda1() { 67 auto f = [](MoveSemantics m) { 68 fmovable(std::move(m)); 69 }; 70 f(MoveSemantics()); 71 } 72 73 template<class T> struct function {}; 74 75 template<typename Result, typename... Args> 76 class function<Result(Args...)> { 77 public: 78 function() = default; operator ()(Args...args) const79 void operator()(Args... args) const { 80 fmovable(std::forward<Args>(args)...); 81 } 82 }; 83 functionInvocation()84void functionInvocation() { 85 function<void(MoveSemantics)> callback; 86 MoveSemantics m; 87 callback(std::move(m)); 88 } 89 lambda2()90void lambda2() { 91 function<void(MoveSemantics)> callback; 92 93 auto f = [callback = std::move(callback)](MoveSemantics m) mutable { 94 callback(std::move(m)); 95 }; 96 f(MoveSemantics()); 97 } 98