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