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 // RUN: -- -std=c++14 5 6 namespace std { 7 8 template <typename> struct remove_reference; 9 template <typename _Tp> struct remove_reference { typedef _Tp type; }; 10 template <typename _Tp> struct remove_reference<_Tp &> { typedef _Tp type; }; 11 template <typename _Tp> struct remove_reference<_Tp &&> { typedef _Tp type; }; 12 13 template <typename _Tp> move(_Tp && __t)14constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) { 15 return static_cast<typename std::remove_reference<_Tp>::type &&>(__t); 16 } 17 18 template <typename _Tp> 19 constexpr _Tp && forward(typename remove_reference<_Tp>::type & __t)20forward(typename remove_reference<_Tp>::type &__t) noexcept { 21 return static_cast<_Tp &&>(__t); 22 } 23 24 } // namespace std 25 26 class NoMoveSemantics { 27 public: 28 NoMoveSemantics(); 29 NoMoveSemantics(const NoMoveSemantics &); 30 31 NoMoveSemantics &operator=(const NoMoveSemantics &); 32 }; 33 34 void callByConstRef(const NoMoveSemantics &); 35 void callByConstRef(int i, const NoMoveSemantics &); 36 moveToConstReferencePositives()37void moveToConstReferencePositives() { 38 NoMoveSemantics obj; 39 40 // Basic case. It is here just to have a single "detected and fixed" case. 41 callByConstRef(std::move(obj)); 42 // 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] 43 // CHECK-FIXES: callByConstRef(obj); 44 } 45 46 struct TriviallyCopyable { 47 int i; 48 }; 49 f(TriviallyCopyable)50void f(TriviallyCopyable) {} 51 g()52void g() { 53 TriviallyCopyable obj; 54 f(std::move(obj)); 55 } 56 57 class MoveSemantics { 58 public: 59 MoveSemantics(); 60 MoveSemantics(MoveSemantics &&); 61 62 MoveSemantics &operator=(MoveSemantics &&); 63 }; 64 65 void fmovable(MoveSemantics); 66 lambda1()67void lambda1() { 68 auto f = [](MoveSemantics m) { 69 fmovable(std::move(m)); 70 }; 71 f(MoveSemantics()); 72 } 73 74 template<class T> struct function {}; 75 76 template<typename Result, typename... Args> 77 class function<Result(Args...)> { 78 public: 79 function() = default; operator ()(Args...args) const80 void operator()(Args... args) const { 81 fmovable(std::forward<Args>(args)...); 82 } 83 }; 84 functionInvocation()85void functionInvocation() { 86 function<void(MoveSemantics)> callback; 87 MoveSemantics m; 88 callback(std::move(m)); 89 } 90 lambda2()91void lambda2() { 92 function<void(MoveSemantics)> callback; 93 94 auto f = [callback = std::move(callback)](MoveSemantics m) mutable { 95 callback(std::move(m)); 96 }; 97 f(MoveSemantics()); 98 } 99