189a1d03eSRichard // RUN: %check_clang_tidy %s performance-move-const-arg %t \ 289a1d03eSRichard // RUN: -config='{CheckOptions: \ 3*e8a3ddafSNathan James // RUN: {performance-move-const-arg.CheckMoveToConstRef: false}}' 489a1d03eSRichard 589a1d03eSRichard namespace std { 689a1d03eSRichard template <typename> 789a1d03eSRichard struct remove_reference; 889a1d03eSRichard 989a1d03eSRichard template <typename _Tp> 1089a1d03eSRichard struct remove_reference { 1189a1d03eSRichard typedef _Tp type; 1289a1d03eSRichard }; 1389a1d03eSRichard 1489a1d03eSRichard template <typename _Tp> 1589a1d03eSRichard struct remove_reference<_Tp &> { 1689a1d03eSRichard typedef _Tp type; 1789a1d03eSRichard }; 1889a1d03eSRichard 1989a1d03eSRichard template <typename _Tp> 2089a1d03eSRichard struct remove_reference<_Tp &&> { 2189a1d03eSRichard typedef _Tp type; 2289a1d03eSRichard }; 2389a1d03eSRichard 2489a1d03eSRichard template <typename _Tp> move(_Tp && __t)2589a1d03eSRichardconstexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) { 2689a1d03eSRichard return static_cast<typename std::remove_reference<_Tp>::type &&>(__t); 2789a1d03eSRichard } 2889a1d03eSRichard 2989a1d03eSRichard template <typename _Tp> 3089a1d03eSRichard constexpr _Tp && forward(typename remove_reference<_Tp>::type & __t)3189a1d03eSRichardforward(typename remove_reference<_Tp>::type &__t) noexcept { 3289a1d03eSRichard return static_cast<_Tp &&>(__t); 3389a1d03eSRichard } 3489a1d03eSRichard 3589a1d03eSRichard } // namespace std 3689a1d03eSRichard 3789a1d03eSRichard struct TriviallyCopyable { 3889a1d03eSRichard int i; 3989a1d03eSRichard }; 4089a1d03eSRichard f(TriviallyCopyable)4189a1d03eSRichardvoid f(TriviallyCopyable) {} 4289a1d03eSRichard g()4389a1d03eSRichardvoid g() { 4489a1d03eSRichard TriviallyCopyable obj; 4589a1d03eSRichard // Some basic test to ensure that other warnings from 4689a1d03eSRichard // performance-move-const-arg are still working and enabled. 4789a1d03eSRichard f(std::move(obj)); 4889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: std::move of the variable 'obj' of the trivially-copyable type 'TriviallyCopyable' has no effect; remove std::move() [performance-move-const-arg] 4989a1d03eSRichard // CHECK-FIXES: f(obj); 5089a1d03eSRichard } 5189a1d03eSRichard 5289a1d03eSRichard class NoMoveSemantics { 5389a1d03eSRichard public: 5489a1d03eSRichard NoMoveSemantics(); 5589a1d03eSRichard NoMoveSemantics(const NoMoveSemantics &); 5689a1d03eSRichard NoMoveSemantics &operator=(const NoMoveSemantics &); 5789a1d03eSRichard }; 5889a1d03eSRichard 5989a1d03eSRichard class MoveSemantics { 6089a1d03eSRichard public: 6189a1d03eSRichard MoveSemantics(); 6289a1d03eSRichard MoveSemantics(MoveSemantics &&); 6389a1d03eSRichard 6489a1d03eSRichard MoveSemantics &operator=(MoveSemantics &&); 6589a1d03eSRichard }; 6689a1d03eSRichard 6789a1d03eSRichard void callByConstRef1(const NoMoveSemantics &); 6889a1d03eSRichard void callByConstRef2(const MoveSemantics &); 6989a1d03eSRichard moveToConstReferencePositives()7089a1d03eSRichardvoid moveToConstReferencePositives() { 7189a1d03eSRichard NoMoveSemantics a; 7289a1d03eSRichard 7389a1d03eSRichard // This call is now allowed since CheckMoveToConstRef is false. 7489a1d03eSRichard callByConstRef1(std::move(a)); 7589a1d03eSRichard 7689a1d03eSRichard MoveSemantics b; 7789a1d03eSRichard 7889a1d03eSRichard // This call is now allowed since CheckMoveToConstRef is false. 7989a1d03eSRichard callByConstRef2(std::move(b)); 8089a1d03eSRichard } 81