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
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.)
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);
&& 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