aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2004-08-07 13:40:10 -0400
committerJason Merrill <jason@gcc.gnu.org>2004-08-07 13:40:10 -0400
commitcc77ae108d3b8cf9aa8bbbeada6c0c1fbcf8920f (patch)
tree252b73c82d55d0b8da42cb892207cf89b9b2d1bc /gcc/cp
parent0737fbff594ae45dc2e37dc2eff51601cdb99e1b (diff)
downloadgcc-cc77ae108d3b8cf9aa8bbbeada6c0c1fbcf8920f.zip
gcc-cc77ae108d3b8cf9aa8bbbeada6c0c1fbcf8920f.tar.gz
gcc-cc77ae108d3b8cf9aa8bbbeada6c0c1fbcf8920f.tar.bz2
Make return in memory explicit.
* function.c (aggregate_value_p): Check DECL_BY_REFERENCE. (assign_parm_find_data_types): Remove code for old front end invisible reference handling. (assign_parms): Handle DECL_BY_REFERENCE on the RESULT_DECL. (expand_function_end): Likewise. * gimplify.c (gimplify_return_expr): Handle a dereferenced RESULT_DECL. * tree-inline.c (copy_body_r): Don't bother looking for &* anymore. (declare_return_variable): Handle DECL_BY_REFERENCE. * cp/cp-gimplify.c (is_invisiref_parm): Also handle RESULT_DECL. (cp_genericize_r): Use convert_from_reference. Don't dereference a RESULT_DECL directly inside a RETURN_EXPR. (cp_genericize): Handle the RESULT_DECL. Unset TREE_ADDRESSABLE. From-SVN: r85675
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/cp-gimplify.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index ed0a6a1..5b96e39 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -267,7 +267,7 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
static inline bool
is_invisiref_parm (tree t)
{
- return (TREE_CODE (t) == PARM_DECL
+ return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
&& DECL_BY_REFERENCE (t));
}
@@ -283,7 +283,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
if (is_invisiref_parm (stmt))
{
- *stmt_p = build_fold_indirect_ref (stmt);
+ *stmt_p = convert_from_reference (stmt);
*walk_subtrees = 0;
return NULL;
}
@@ -302,6 +302,11 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
*stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
*walk_subtrees = 0;
}
+ else if (TREE_CODE (stmt) == RETURN_EXPR
+ && TREE_OPERAND (stmt, 0)
+ && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+ /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
+ *walk_subtrees = 0;
else if (DECL_P (stmt) || TYPE_P (stmt))
*walk_subtrees = 0;
@@ -331,12 +336,23 @@ cp_genericize (tree fndecl)
{
if (DECL_ARG_TYPE (t) == TREE_TYPE (t))
abort ();
- DECL_BY_REFERENCE (t) = 1;
TREE_TYPE (t) = DECL_ARG_TYPE (t);
+ DECL_BY_REFERENCE (t) = 1;
+ TREE_ADDRESSABLE (t) = 0;
relayout_decl (t);
}
}
+ /* Do the same for the return value. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
+ {
+ t = DECL_RESULT (fndecl);
+ TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
+ DECL_BY_REFERENCE (t) = 1;
+ TREE_ADDRESSABLE (t) = 0;
+ relayout_decl (t);
+ }
+
/* If we're a clone, the body is already GIMPLE. */
if (DECL_CLONED_FUNCTION_P (fndecl))
return;