// PR c++/90428 // { dg-do compile { target c++11 } } // { dg-options "-Wredundant-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&&) = delete; }; struct S : T { }; struct W { W(const W&); W(W&&) = delete; W(const W&&); }; T f1(T t) { const T& rt = t; return std::move(rt); // { dg-warning "redundant move" } } T f2(const T& t) { return std::move(t); // { dg-warning "redundant move" } } W f3(const W& w) { return std::move(w); } T f4(const S& s) { return std::move(s); } T f5(const T t) { return std::move(t); // { dg-warning "redundant move" } } struct S1 { S1(S1 &&) = delete; S1(const S1&); }; struct S2: S1 {}; S1 f3(const S2 s) { return std::move(s); // { dg-warning "redundant move" } }