xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg-const-ref.cpp (revision e8a3ddafe063c970df9c23e803812369abde4c82)
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)2589a1d03eSRichard constexpr 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)3189a1d03eSRichard forward(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)4189a1d03eSRichard void f(TriviallyCopyable) {}
4289a1d03eSRichard 
g()4389a1d03eSRichard void 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()7089a1d03eSRichard void 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