aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2005-02-17 00:37:19 -0500
committerJason Merrill <jason@gcc.gnu.org>2005-02-17 00:37:19 -0500
commiteff9a5d03465b8abf2714389f7b4b46559454286 (patch)
treebccf57f0eb578bf24376faa22b48c836b25ff92a /gcc
parentbeb5f8072a53de566c0956da3b62dab02d12382a (diff)
downloadgcc-eff9a5d03465b8abf2714389f7b4b46559454286.zip
gcc-eff9a5d03465b8abf2714389f7b4b46559454286.tar.gz
gcc-eff9a5d03465b8abf2714389f7b4b46559454286.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/gimplify.c63
2 files changed, 69 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 56fd26a..3a18b31 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-02-17 Jason Merrill <jason@redhat.com>
+
+ PR mudflap/19319, c++/19317
+ * gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return
+ slot explicit.
+
2005-02-17 Gerald Pfeifer <gerald@pfeifer.com>
* doc/install.texi (Specific): Update link for Darwin-specific
@@ -287,11 +293,6 @@
2005-02-13 Jason Merrill <jason@redhat.com>
- [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 d461d77..89fd5c7 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;