1 // PR c++/87378 2 // { dg-do compile { target c++11 } } 3 // { dg-options "-Wredundant-move" } 4 5 // Define std::move. 6 namespace std { 7 template<typename _Tp> 8 struct remove_reference 9 { typedef _Tp type; }; 10 11 template<typename _Tp> 12 struct remove_reference<_Tp&> 13 { typedef _Tp type; }; 14 15 template<typename _Tp> 16 struct remove_reference<_Tp&&> 17 { typedef _Tp type; }; 18 19 template<typename _Tp> 20 constexpr typename std::remove_reference<_Tp>::type&& 21 move(_Tp&& __t) noexcept 22 { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } 23 } 24 25 struct S1 { S1(S1 &&); }; 26 struct S2 : S1 {}; 27 28 S1 29 f (S2 s) 30 { 31 return std::move(s); // { dg-bogus "redundant move in return statement" } 32 } 33 34 struct R1 { 35 R1(R1 &&); 36 R1(const R1 &&); 37 }; 38 struct R2 : R1 {}; 39 40 R1 41 f2 (const R2 s) 42 { 43 return std::move(s); // { dg-bogus "redundant move in return statement" } 44 } 45 46 struct T1 { 47 T1(const T1 &); 48 T1(T1 &&); 49 T1(const T1 &&); 50 }; 51 struct T2 : T1 {}; 52 53 T1 54 f3 (const T2 s) 55 { 56 // Without std::move: const T1 & 57 // With std::move: const T1 && 58 return std::move(s); // { dg-bogus "redundant move in return statement" } 59 } 60