From 0b5957b92124b679b39d8796e56383ab661fbecc Mon Sep 17 00:00:00 2001 From: mpolacek Date: Fri, 11 Jan 2019 23:21:40 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@267862 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/typeck.c | 5 +- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C | 53 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C | 43 +++++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wredundant-move5.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wredundant-move6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0eb669b3eac2..9c661a5ced24 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-01-11 Marek Polacek + + 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 PR c++/88312 - pack expansion of decltype. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e399cd3fe45b..43d2899a3c4d 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 f991df8673c4..11845e3d0cc0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-01-11 Marek Polacek + + 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 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 000000000000..0e2ec46d11e0 --- /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 + struct remove_reference + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&&> + { typedef _Tp type; }; + + template + constexpr typename std::remove_reference<_Tp>::type&& + move(_Tp&& __t) noexcept + { return static_cast::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 000000000000..5808a78638ea --- /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 + struct remove_reference + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&&> + { typedef _Tp type; }; + + template + constexpr typename std::remove_reference<_Tp>::type&& + move(_Tp&& __t) noexcept + { return static_cast::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(); +} -- 2.47.2