blob: 5c9fc92c3479fee7ff6ca1de42c9a925838309a9 [file] [log] [blame]
// PR c++/81159
// { dg-do compile { target c++11 } }
// { dg-options "-Wself-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); }
}
int g;
struct S {
int x;
S(S&& o) {
x = std::move (x); // { dg-warning "moving '\[^\n\r]*S::x' of type .int. to itself" }
x = std::move (o.x);
o.x = std::move (x);
o.x = std::move (o.x); // { dg-warning "moving 'o.S::x' of type .int. to itself" }
}
void foo (int x) {
x = std::move (x); // { dg-warning "moving 'x' of type .int. to itself" }
}
};
struct X {
int x;
X(int x) : x(std::move (x)) { }
};
struct A {};
struct B { A a; };
struct C { C(); ~C(); };
struct D { D(); D(const D&); D(D&&); D& operator=(const D&); };
void
test ()
{
int i = 42;
i = std::move (i); // { dg-warning "moving 'i' of type .int. to itself" }
(i) = std::move (i); // { dg-warning "moving 'i' of type .int. to itself" }
g = std::move (g); // { dg-warning "moving 'g' of type .int. to itself" }
(g) = std::move (g); // { dg-warning "moving 'g' of type .int. to itself" }
A a;
a = std::move (a); // { dg-warning "moving 'a' of type .A. to itself" }
(a) = std::move (a); // { dg-warning "moving 'a' of type .A. to itself" }
B b;
b = std::move (b); // { dg-warning "moving 'b' of type .B. to itself" }
(b) = std::move (b); // { dg-warning "moving 'b' of type .B. to itself" }
b.a = std::move (b.a); // { dg-warning "moving 'b.B::a' of type .A. to itself" }
(b.a) = std::move (b.a); // { dg-warning "moving 'b.B::a' of type .A. to itself" }
C c;
c = std::move (c); // { dg-warning "moving 'c' of type .C. to itself" }
D d;
d = std::move (d); // { dg-warning "moving 'd' of type .D. to itself" }
}
template<typename T>
void ttest ()
{
T t;
t = std::move (t); // { dg-warning "moving 't' of type .A. to itself" }
}
template void ttest<A>();
void
testref (int &r, int &&rr)
{
r = std::move (r); // { dg-warning "moving 'r' of type .int. to itself" }
rr = std::move (rr); // { dg-warning "moving 'rr' of type .int. to itself" }
}
// Test various other arguments to std::move.
template<typename T>
void
testargs (T *Tptr, T **Tpptr, T& Tref, T&& Trref, const T *Tcptr)
{
Tptr = std::move (Tptr); // { dg-warning "moving 'Tptr' of type 'int\\*' to itself" }
*Tptr = std::move (*Tptr); // { dg-warning "moving '\\* Tptr' of type 'int' to itself" }
*Tptr = std::move (*(Tptr)); // { dg-warning "moving '\\* Tptr' of type 'int' to itself" }
*(Tptr) = std::move (*Tptr); // { dg-warning "moving '\\* Tptr' of type 'int' to itself" }
*(Tptr + 1) = std::move (*(Tptr + 1)); // { dg-warning "moving '\[^\n\r]*Tptr\[^\n\r]*' of type 'int' to itself" }
*(Tptr + 1) = std::move (*(Tptr + 2));
(*(Tptr)) = std::move (*Tptr); // { dg-warning "moving '\\* Tptr' of type 'int' to itself" }
*Tpptr = std::move (*Tpptr); // { dg-warning "moving '\\* Tpptr' of type 'int\\*' to itself" }
**Tpptr = std::move (**Tpptr); // { dg-warning "moving '\\* \\* Tpptr' of type 'int' to itself" }
Tref = std::move (Tref); // { dg-warning "moving 'Tref' of type 'int' to itself" }
Trref = std::move (Trref); // { dg-warning "moving 'Trref' of type 'int' to itself" }
Tcptr = std::move (Tcptr); // { dg-warning "moving 'Tcptr' of type 'const int\\*' to itself" }
(Tptr) = std::move (Tptr); // { dg-warning "moving 'Tptr' of type 'int\\*' to itself" }
(*Tptr) = std::move (*Tptr); // { dg-warning "moving '\\* Tptr' of type 'int' to itself" }
(*Tpptr) = std::move (*Tpptr); // { dg-warning "moving '\\* Tpptr' of type 'int\\*' to itself" }
(**Tpptr) = std::move (**Tpptr); // { dg-warning "moving '\\* \\* Tpptr' of type 'int' to itself" }
(*(*(Tpptr))) = std::move (**Tpptr); // { dg-warning "moving '\\* \\* Tpptr' of type 'int' to itself" }
(Tref) = std::move (Tref); // { dg-warning "moving 'Tref' of type 'int' to itself" }
(Trref) = std::move (Trref); // { dg-warning "moving 'Trref' of type 'int' to itself" }
(Tcptr) = std::move (Tcptr); // { dg-warning "moving 'Tcptr' of type 'const int\\*' to itself" }
}
void
call_testargs ()
{
int i = 42;
int *p = &i;
testargs<int>(&i, &p, i, 42, &i);
}