From 1439f35553a8aaa034deda26b4072bdec4af8f79 Mon Sep 17 00:00:00 2001 From: Marek Polacek 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. From-SVN: r267862 --- 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 0eb669b3eac..9c661a5ced2 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 e399cd3fe45..43d2899a3c4 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 f991df8673c..11845e3d0cc 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 00000000000..0e2ec46d11e --- /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 00000000000..5808a78638e --- /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.30.2