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