mirror of git://gcc.gnu.org/git/gcc.git
PR c++/86982, -Wreturn-local-addr and std::move and std::forward.
* typeck.c (maybe_warn_about_returning_address_of_local): Handle calls to std::move or std::forward. (is_std_forward_p): New function. * g++.dg/warn/Wreturn-local-addr-5.C: New test. From-SVN: r264139
This commit is contained in:
parent
4497d88fe2
commit
308d9cda32
|
|
@ -5,6 +5,11 @@
|
|||
out if performing the maybe-rvalue overload resolution and a conversion
|
||||
function is getting called.
|
||||
|
||||
PR c++/86982, -Wreturn-local-addr and std::move and std::forward.
|
||||
* typeck.c (maybe_warn_about_returning_address_of_local): Handle calls
|
||||
to std::move or std::forward.
|
||||
(is_std_forward_p): New function.
|
||||
|
||||
2018-09-05 Pádraig Brady <p@draigbrady.com>
|
||||
|
||||
PR c++/87185
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ static tree lookup_destructor (tree, tree, tree, tsubst_flags_t);
|
|||
static void error_args_num (location_t, tree, bool);
|
||||
static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
|
||||
tsubst_flags_t);
|
||||
static bool is_std_move_p (tree);
|
||||
static bool is_std_forward_p (tree);
|
||||
|
||||
/* Do `exp = require_complete_type (exp);' to make sure exp
|
||||
does not have an incomplete type. (That includes void types.)
|
||||
|
|
@ -9071,6 +9073,15 @@ maybe_warn_about_returning_address_of_local (tree retval)
|
|||
STRIP_NOPS (whats_returned);
|
||||
}
|
||||
|
||||
/* As a special case, we handle a call to std::move or std::forward. */
|
||||
if (TREE_CODE (whats_returned) == CALL_EXPR
|
||||
&& (is_std_move_p (whats_returned)
|
||||
|| is_std_forward_p (whats_returned)))
|
||||
{
|
||||
tree arg = CALL_EXPR_ARG (whats_returned, 0);
|
||||
return maybe_warn_about_returning_address_of_local (arg);
|
||||
}
|
||||
|
||||
if (TREE_CODE (whats_returned) != ADDR_EXPR)
|
||||
return false;
|
||||
whats_returned = TREE_OPERAND (whats_returned, 0);
|
||||
|
|
@ -9136,6 +9147,23 @@ decl_in_std_namespace_p (tree decl)
|
|||
&& DECL_NAMESPACE_STD_P (decl_namespace_context (decl)));
|
||||
}
|
||||
|
||||
/* Returns true if FN, a CALL_EXPR, is a call to std::forward. */
|
||||
|
||||
static bool
|
||||
is_std_forward_p (tree fn)
|
||||
{
|
||||
/* std::forward only takes one argument. */
|
||||
if (call_expr_nargs (fn) != 1)
|
||||
return false;
|
||||
|
||||
tree fndecl = cp_get_callee_fndecl_nofold (fn);
|
||||
if (!decl_in_std_namespace_p (fndecl))
|
||||
return false;
|
||||
|
||||
tree name = DECL_NAME (fndecl);
|
||||
return name && id_equal (name, "forward");
|
||||
}
|
||||
|
||||
/* Returns true if FN, a CALL_EXPR, is a call to std::move. */
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2018-09-05 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/86982, -Wreturn-local-addr and std::move and std::forward.
|
||||
* g++.dg/warn/Wreturn-local-addr-5.C: New test.
|
||||
|
||||
2018-09-05 Cesar Philippidis <cesar@codesourcery.com>
|
||||
Bernd Schmidt <bernds_cb1@t-online.de>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
// PR c++/86982
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
#include <utility>
|
||||
|
||||
int&& f() { int i = 0; return std::move(i); } // { dg-warning "reference to local variable" }
|
||||
int&& g() { int i = 0; return std::forward<int>(i); } // { dg-warning "reference to local variable" }
|
||||
int&& h() { long l = 0; return std::forward<int>(l); } // { dg-warning "reference to temporary" }
|
||||
Loading…
Reference in New Issue