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
|
out if performing the maybe-rvalue overload resolution and a conversion
|
||||||
function is getting called.
|
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>
|
2018-09-05 Pádraig Brady <p@draigbrady.com>
|
||||||
|
|
||||||
PR c++/87185
|
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 void error_args_num (location_t, tree, bool);
|
||||||
static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
|
static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
|
||||||
tsubst_flags_t);
|
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
|
/* Do `exp = require_complete_type (exp);' to make sure exp
|
||||||
does not have an incomplete type. (That includes void types.)
|
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);
|
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)
|
if (TREE_CODE (whats_returned) != ADDR_EXPR)
|
||||||
return false;
|
return false;
|
||||||
whats_returned = TREE_OPERAND (whats_returned, 0);
|
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)));
|
&& 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. */
|
/* Returns true if FN, a CALL_EXPR, is a call to std::move. */
|
||||||
|
|
||||||
static bool
|
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>
|
2018-09-05 Cesar Philippidis <cesar@codesourcery.com>
|
||||||
Bernd Schmidt <bernds_cb1@t-online.de>
|
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