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   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 struct U { U(T); };
27 
28 template<typename Tp>
29 T
30 fn1 ()
31 {
32   T t;
33   // Non-dependent type.
34   return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" }
35 }
36 
37 template<typename Tp1, typename Tp2>
38 Tp1
39 fn2 ()
40 {
41   Tp2 t;
42   return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" }
43 }
44 
45 template<typename Tp1, typename Tp2>
46 Tp1
47 fn3 ()
48 {
49   Tp2 t;
50   return std::move (t);
51 }
52 
53 int
54 main ()
55 {
56   fn1<T>();
57   fn2<T, T>();
58   fn3<U, T>();
59 }
60