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