1 // PR c++/86981 2 // { dg-do compile { target c++11 } } 3 // { dg-options "-Wpessimizing-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 T { 26 T() { } 27 T(const T&) { } 28 T(T&&) { } 29 }; 30 struct U { 31 U() { } 32 U(const U&) { } 33 U(U&&) { } 34 U(T) { } 35 }; 36 37 T g; 38 39 T 40 fn1 () 41 { 42 T t; 43 return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" } 44 } 45 46 T 47 fn2 () 48 { 49 // Not a local variable. 50 return std::move (g); 51 } 52 53 int 54 fn3 () 55 { 56 int i = 42; 57 // Not a class type. 58 return std::move (i); 59 } 60 61 T 62 fn4 (bool b) 63 { 64 T t; 65 if (b) 66 throw std::move (t); 67 return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" } 68 } 69 70 T 71 fn5 (T t) 72 { 73 // Function parameter; std::move is redundant but not pessimizing. 74 return std::move (t); 75 } 76 77 U 78 fn6 (T t, U u, bool b) 79 { 80 if (b) 81 return std::move (t); 82 else 83 // Function parameter; std::move is redundant but not pessimizing. 84 return std::move (u); 85 } 86 87 U 88 fn6 (bool b) 89 { 90 T t; 91 U u; 92 if (b) 93 return std::move (t); 94 else 95 return std::move (u); // { dg-warning "moving a local object in a return statement prevents copy elision" } 96 } 97 98 T 99 fn7 () 100 { 101 static T t; 102 // Non-local; don't warn. 103 return std::move (t); 104 } 105 106 T 107 fn8 () 108 { 109 return T(); 110 } 111 112 T 113 fn9 (int i) 114 { 115 T t; 116 117 switch (i) 118 { 119 case 1: 120 return std::move ((t)); // { dg-warning "moving a local object in a return statement prevents copy elision" } 121 case 2: 122 return (std::move (t)); // { dg-warning "moving a local object in a return statement prevents copy elision" } 123 default: 124 return (std::move ((t))); // { dg-warning "moving a local object in a return statement prevents copy elision" } 125 } 126 } 127 128 int 129 fn10 () 130 { 131 return std::move (42); 132 } 133