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
This commit is contained in:
Marek Polacek 2019-01-11 23:21:40 +00:00 committed by Marek Polacek
parent 378b9abe56
commit 1439f35553
5 changed files with 111 additions and 2 deletions

View File

@ -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.

View File

@ -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))

View File

@ -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

View File

@ -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" }
}
};

View File

@ -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();
}