diff options
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move5.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move1.C | 106 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move2.C | 57 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move3.C | 43 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move4.C | 86 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto52.C | 6 |
6 files changed, 312 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move5.C b/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move5.C new file mode 100644 index 00000000000..02ad2113505 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move5.C @@ -0,0 +1,14 @@ +// PR c++/87080 +// { dg-do compile { target c++11 } } +// { dg-options "-Wpessimizing-move" } + +struct a { + template<typename b> a &operator<<(b); +}; +a c(); +template<typename> +a fn2() +{ + int d = 42; + return c() << d; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move1.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move1.C new file mode 100644 index 00000000000..5d4a25dbc3b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move1.C @@ -0,0 +1,106 @@ +// PR c++/87029 +// { 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&&) { } +}; + +struct U { + U() { } + U(const U&) { } + U(U&&) { } + U(T) { } +}; + +T +fn1 (T t) +{ + return t; +} + +T +fn2 (T t) +{ + // Will use move even without std::move. + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +T +fn3 (const T t) +{ + // t is const: will decay into copy. + return t; +} + +T +fn4 (const T t) +{ + // t is const: will decay into copy despite std::move, so it's redundant. + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +int +fn5 (int i) +{ + // Not a class type. + return std::move (i); +} + +T +fn6 (T t, bool b) +{ + if (b) + throw std::move (t); + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +U +fn7 (T t) +{ + // Core 1579 means we'll get a move here. + return t; +} + +U +fn8 (T t) +{ + // Core 1579 means we'll get a move here. Even without std::move. + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +T +fn9 (T& t) +{ + // T is a reference and the move isn't redundant. + return std::move (t); +} + +T +fn10 (T&& t) +{ + // T is a reference and the move isn't redundant. + return std::move (t); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move2.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move2.C new file mode 100644 index 00000000000..f181afeeb84 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move2.C @@ -0,0 +1,57 @@ +// PR c++/87029 +// { 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 { }; +struct U { U(T); }; + +template<typename Tp> +T +fn1 (T t) +{ + // Non-dependent type. + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +template<typename Tp1, typename Tp2> +Tp1 +fn2 (Tp2 t) +{ + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +template<typename Tp1, typename Tp2> +Tp1 +fn3 (Tp2 t) +{ + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +int +main () +{ + T t; + fn1<T>(t); + fn2<T, T>(t); + fn3<U, T>(t); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move3.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move3.C new file mode 100644 index 00000000000..7084134e370 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move3.C @@ -0,0 +1,43 @@ +// PR c++/87029 +// { 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 +fn1 (T t) +{ + return (1, std::move (t)); +} + +T +fn2 (T t) +{ + return [&](){ return std::move (t); }(); +} + +T +fn3 (T t) +{ + return [=](){ return std::move (t); }(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move4.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move4.C new file mode 100644 index 00000000000..aa89e46de99 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move4.C @@ -0,0 +1,86 @@ +// PR c++/87029 +// { 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&&) { } +}; + +struct U { + U() { } + U(const U&) { } + U(U&&) { } + U(T) { } +}; + +U +fn1 (T t, bool b) +{ + if (b) + return t; + else + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +U +fn2 (bool b) +{ + T t; + if (b) + return t; + else + return std::move (t); // { dg-warning "redundant move in return statement" } +} + +U +fn3 (bool b) +{ + static T t; + if (b) + return t; + else + return std::move (t); +} + +T g; + +U +fn4 (bool b) +{ + if (b) + return g; + else + return std::move (g); +} + +long int +fn5 (bool b) +{ + int i = 42; + if (b) + return i; + else + return std::move (i); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/auto52.C b/gcc/testsuite/g++.dg/cpp0x/auto52.C new file mode 100644 index 00000000000..9bfe7c754b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto52.C @@ -0,0 +1,6 @@ +// PR c++/86942 +// { dg-do compile { target c++11 } } + +using T = auto() -> int; +using U = void() -> int; // { dg-error "function with trailing return type not declared with .auto." } +using W = auto(); // { dg-error "invalid use of .auto." } |