1 // PR c++/87029
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 T {
26   T() { }
27   T(const T&) { }
28   T(T&&) { }
29 };
30 
31 struct U {
32   U() { }
33   U(const U&) { }
34   U(U&&) { }
35   U(T) { }
36 };
37 
38 U
39 fn1 (T t, bool b)
40 {
41   if (b)
42     return t;
43   else
44     return std::move (t); // { dg-warning "redundant move in return statement" }
45 }
46 
47 U
48 fn2 (bool b)
49 {
50   T t;
51   if (b)
52     return t;
53   else
54     return std::move (t); // { dg-warning "redundant move in return statement" }
55 }
56 
57 U
58 fn3 (bool b)
59 {
60   static T t;
61   if (b)
62     return t;
63   else
64     return std::move (t);
65 }
66 
67 T g;
68 
69 U
70 fn4 (bool b)
71 {
72   if (b)
73     return g;
74   else
75     return std::move (g);
76 }
77 
78 long int
79 fn5 (bool b)
80 {
81   int i = 42;
82   if (b)
83     return i;
84   else
85     return std::move (i);
86 }
87