From: Marek Polacek Date: Thu, 6 Sep 2018 00:38:13 +0000 (+0000) Subject: PR c++/86982, -Wreturn-local-addr and std::move and std::forward. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=308d9cda32faed5d49ce3d0732b4ff465c423300;p=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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b4ec9f4b449..d5879f8cd0e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 PR c++/87185 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 84cf4c478aa..9fa4c16bf14 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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, 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ccc2442c3e..e22ede07c15 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-09-05 Marek Polacek + + 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 Bernd Schmidt diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C new file mode 100644 index 00000000000..76096279a64 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-5.C @@ -0,0 +1,8 @@ +// PR c++/86982 +// { dg-do compile { target c++11 } } + +#include + +int&& f() { int i = 0; return std::move(i); } // { dg-warning "reference to local variable" } +int&& g() { int i = 0; return std::forward(i); } // { dg-warning "reference to local variable" } +int&& h() { long l = 0; return std::forward(l); } // { dg-warning "reference to temporary" }