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:
parent
2b0a62741e
commit
ef7e79a367
gcc
@ -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
|
||||
|
38
gcc/testsuite/g++.dg/cpp0x/Wredundant-move8.C
Normal file
38
gcc/testsuite/g++.dg/cpp0x/Wredundant-move8.C
Normal file
@ -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" }
|
||||
}
|
||||
};
|
108
gcc/testsuite/g++.dg/cpp0x/Wredundant-move9.C
Normal file
108
gcc/testsuite/g++.dg/cpp0x/Wredundant-move9.C
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user