From eff9a5d03465b8abf2714389f7b4b46559454286 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 17 Feb 2005 00:37:19 -0500 Subject: [PATCH] PR mudflap/19319, c++/19317 PR mudflap/19319, c++/19317 * gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return slot explicit. From-SVN: r95150 --- gcc/ChangeLog | 11 +++++---- gcc/gimplify.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56fd26aba1d..3a18b310deb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-02-17 Jason Merrill + + PR mudflap/19319, c++/19317 + * gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return + slot explicit. + 2005-02-17 Gerald Pfeifer * doc/install.texi (Specific): Update link for Darwin-specific @@ -287,11 +293,6 @@ 2005-02-13 Jason Merrill - [reverted temporarily] - PR mudflap/19319 - * gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return - slot explicit. - PR c++/16405 * fold-const.c (fold_indirect_ref_1): Split out from... (build_fold_indirect_ref): Here. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d461d776ee8..89fd5c7e4f4 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2913,6 +2913,69 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, ret = GS_UNHANDLED; break; + case CALL_EXPR: + /* For calls that return in memory, give *to_p as the CALL_EXPR's + return slot so that we don't generate a temporary. */ + if (aggregate_value_p (*from_p, *from_p)) + { + tree init = *from_p; + tree fn = TREE_OPERAND (init, 0); + tree args = TREE_OPERAND (init, 1); + tree rettype = TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))); + tree arg = *to_p; + tree type; + + /* Only use the original target if *to_p isn't already + addressable; if its address escapes, and the called function + uses the NRV optimization, a conforming program could see + *to_p change before the called function returns. This is + c++/19317. */ + bool use_temp = !is_gimple_non_addressable (*to_p); + + /* A CALL_EXPR with an explicit return slot argument should + never appear on the RHS of a MODIFY_EXPR. */ + if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (*from_p)) + abort (); + + if (use_temp) + { + arg = create_tmp_var (rettype, "ret"); + *from_p = arg; + } + + type = TREE_TYPE (arg); + /* FIXME: Mark the address as not escaping. */ + lang_hooks.mark_addressable (arg); + arg = build1 (ADDR_EXPR, build_pointer_type (type), arg); + /* The return type might have different cv-quals from arg. */ + arg = convert (build_pointer_type (rettype), arg); + args = tree_cons (NULL_TREE, arg, args); + init = build3 (CALL_EXPR, rettype, fn, args, NULL_TREE); + CALL_EXPR_HAS_RETURN_SLOT_ADDR (init) = 1; + TREE_USED (init) = 1; + + if (use_temp) + { + gimplify_and_add (init, pre_p); + ret = GS_OK; + break; + } + else if (want_value) + { + gimplify_and_add (init, pre_p); + *expr_p = *to_p; + return GS_OK; + } + else + { + *expr_p = init; + return GS_OK; + } + } + else + ret = GS_UNHANDLED; + break; + default: ret = GS_UNHANDLED; break; -- 2.30.2