diff options
author | Marek Polacek <polacek@redhat.com> | 2019-01-11 23:21:40 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-01-11 23:21:40 +0000 |
commit | 1439f35553a8aaa034deda26b4072bdec4af8f79 (patch) | |
tree | 0118cad4ed344b3d30e541633c945294301995f5 | |
parent | 378b9abe569d030bbe33f74a55b55519da9bf4bb (diff) | |
download | gcc-1439f35553a8aaa034deda26b4072bdec4af8f79.zip gcc-1439f35553a8aaa034deda26b4072bdec4af8f79.tar.gz gcc-1439f35553a8aaa034deda26b4072bdec4af8f79.tar.bz2 |
PR c++/88692, c++/87882 - -Wredundant-move false positive with *this.
* typeck.c (maybe_warn_pessimizing_move): Return if ARG isn't
ADDR_EXPR.
* g++.dg/cpp0x/Wredundant-move5.C: New test.
* g++.dg/cpp0x/Wredundant-move6.C: New test.
From-SVN: r267862
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C | 53 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C | 43 |
5 files changed, 111 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0eb669b..9c661a5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-01-11 Marek Polacek <polacek@redhat.com> + + PR c++/88692, c++/87882 - -Wredundant-move false positive with *this. + * typeck.c (maybe_warn_pessimizing_move): Return if ARG isn't + ADDR_EXPR. + 2019-01-11 Jason Merrill <jason@redhat.com> PR c++/88312 - pack expansion of decltype. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e399cd3..43d2899 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9412,8 +9412,9 @@ maybe_warn_pessimizing_move (tree retval, tree functype) { tree arg = CALL_EXPR_ARG (fn, 0); STRIP_NOPS (arg); - if (TREE_CODE (arg) == ADDR_EXPR) - arg = TREE_OPERAND (arg, 0); + if (TREE_CODE (arg) != ADDR_EXPR) + return; + arg = TREE_OPERAND (arg, 0); arg = convert_from_reference (arg); /* Warn if we could do copy elision were it not for the move. */ if (can_do_nrvo_p (arg, functype)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f991df8..11845e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-01-11 Marek Polacek <polacek@redhat.com> + + PR c++/88692, c++/87882 - -Wredundant-move false positive with *this. + * g++.dg/cpp0x/Wredundant-move5.C: New test. + * g++.dg/cpp0x/Wredundant-move6.C: New test. + 2019-01-11 Jakub Jelinek <jakub@redhat.com> PR middle-end/85956 diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C new file mode 100644 index 0000000..0e2ec46 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C @@ -0,0 +1,53 @@ +// PR c++/88692 +// { 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 X { + X f() && { + return std::move(*this); // { dg-bogus "redundant move in return statement" } + } + + X f2() & { + return std::move(*this); // { dg-bogus "redundant move in return statement" } + } + + X f3() { + return std::move(*this); // { dg-bogus "redundant move in return statement" } + } +}; + +struct S { int i; int j; }; + +struct Y { + S f1 (S s) { + return std::move (s); // { dg-warning "redundant move in return statement" } + } + + S f2 (S* s) { + return std::move (*s); // { dg-bogus "redundant move in return statement" } + } + + S f3 (S** s) { + return std::move (**s); // { dg-bogus "redundant move in return statement" } + } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C new file mode 100644 index 0000000..5808a78 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C @@ -0,0 +1,43 @@ +// PR c++/87882 +// { 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 Foo { + Foo Bar() { + return std::move(*this); // { dg-bogus "redundant move in return statement" } + } + Foo Baz() { + return *this; + } + int i; +}; + +void Move(Foo & f) +{ + f = Foo{}.Bar(); +} + +void NoMove(Foo & f) +{ + f = Foo{}.Baz(); +} |