2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-25 08:10:29 +08:00

PR c++/89660 - bogus error with -Wredundant-move.

* typeck.c (maybe_warn_pessimizing_move): Only accept (T &) &arg
	as the std::move's argument.  Don't call convert_for_initialization
	when warn_redundant_move isn't on.

	* g++.dg/cpp0x/Wredundant-move8.C: New test.
	* g++.dg/cpp0x/Wredundant-move9.C: New test.

From-SVN: r269660
This commit is contained in:
Marek Polacek 2019-03-13 20:04:33 +00:00 committed by Marek Polacek
parent 2b0a62741e
commit ef7e79a367
5 changed files with 161 additions and 3 deletions

@ -12,6 +12,11 @@
* parser.c (cp_parser_lambda_introducer): Give error when combining
init-capture and simple-capture.
PR c++/89660 - bogus error with -Wredundant-move.
* typeck.c (maybe_warn_pessimizing_move): Only accept (T &) &arg
as the std::move's argument. Don't call convert_for_initialization
when warn_redundant_move isn't on.
2019-03-11 Jason Merrill <jason@redhat.com>
PR c++/86521 - wrong overload resolution with ref-qualifiers.

@ -9409,7 +9409,7 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
if (!CLASS_TYPE_P (functype))
return;
/* We're looking for *std::move<T&> (&arg). */
/* We're looking for *std::move<T&> ((T &) &arg). */
if (REFERENCE_REF_P (retval)
&& TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
{
@ -9417,7 +9417,9 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
if (is_std_move_p (fn))
{
tree arg = CALL_EXPR_ARG (fn, 0);
STRIP_NOPS (arg);
if (TREE_CODE (arg) != NOP_EXPR)
return;
arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (arg) != ADDR_EXPR)
return;
arg = TREE_OPERAND (arg, 0);
@ -9433,7 +9435,8 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
}
/* Warn if the move is redundant. It is redundant when we would
do maybe-rvalue overload resolution even without std::move. */
else if (treat_lvalue_as_rvalue_p (arg, /*parm_ok*/true))
else if (warn_redundant_move
&& treat_lvalue_as_rvalue_p (arg, /*parm_ok*/true))
{
/* Make sure that the overload resolution would actually succeed
if we removed the std::move call. */

@ -3,6 +3,10 @@
PR c++/89686 - mixing init-capture and simple-capture in lambda.
* g++.dg/cpp2a/lambda-pack-init2.C: New test.
PR c++/89660 - bogus error with -Wredundant-move.
* g++.dg/cpp0x/Wredundant-move8.C: New test.
* g++.dg/cpp0x/Wredundant-move9.C: New test.
2019-03-13 Janus Weil <janus@gcc.gnu.org>
PR fortran/89601

@ -0,0 +1,38 @@
// PR c++/89660
// { 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); }
}
template <typename S> struct D {
template <typename T> D (D<T> x) : k(&x.foo ()) {}
S &foo ();
int *k;
};
D<int> bar ();
struct F {
D<int> baz () {
D<F> f = bar ();
return std::move (*reinterpret_cast<D<int> *> (&f)); // { dg-bogus "redundant move in return statement" }
}
};

@ -0,0 +1,108 @@
// { 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); }
}
template<typename Tp>
struct T {
T() { }
T(const T&) { }
T(T&&) { }
};
template<typename Tp>
struct U {
U() { }
U(const U&) { }
U(U&&) { }
U(T<Tp>) { }
};
T<int>
fn1 (T<int> t)
{
return t;
}
T<int>
fn2 (T<int> t)
{
// Will use move even without std::move.
return std::move (t); // { dg-warning "redundant move in return statement" }
}
T<int>
fn3 (const T<int> t)
{
// t is const: will decay into copy.
return t;
}
T<int>
fn4 (const T<int> t)
{
// t is const: will decay into copy despite std::move, so it's redundant.
// We used to warn about this, but no longer since c++/87378.
return std::move (t);
}
int
fn5 (int i)
{
// Not a class type.
return std::move (i);
}
T<int>
fn6 (T<int> t, bool b)
{
if (b)
throw std::move (t);
return std::move (t); // { dg-warning "redundant move in return statement" }
}
U<int>
fn7 (T<int> t)
{
// Core 1579 means we'll get a move here.
return t;
}
U<int>
fn8 (T<int> 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<int>
fn9 (T<int>& t)
{
// T is a reference and the move isn't redundant.
return std::move (t);
}
T<int>
fn10 (T<int>&& t)
{
// T is a reference and the move isn't redundant.
return std::move (t);
}