diff options
author | Jason Merrill <jason@redhat.com> | 2003-05-19 12:17:32 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2003-05-19 12:17:32 -0400 |
commit | 68594ce757081d3fc7b7b7eaee1e4651d17d0d86 (patch) | |
tree | 699a131e3b4461d7c0822bad2bb16a829fb39ea1 /gcc/tree-inline.c | |
parent | b041fbe6137dd6b420fb869d17c6e7e4baaa7e55 (diff) | |
download | gcc-68594ce757081d3fc7b7b7eaee1e4651d17d0d86.zip gcc-68594ce757081d3fc7b7b7eaee1e4651d17d0d86.tar.gz gcc-68594ce757081d3fc7b7b7eaee1e4651d17d0d86.tar.bz2 |
tree-inline.c (copy_body_r): Avoid generating &* during inline substitution.
* tree-inline.c (copy_body_r): Avoid generating &* during inline
substitution.
From-SVN: r66964
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index d2cf66a..1387b99 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -546,19 +546,10 @@ copy_body_r (tp, walk_subtrees, data) knows not to copy VAR_DECLs, etc., so this is safe. */ else { - copy_tree_r (tp, walk_subtrees, NULL); - - /* The copied TARGET_EXPR has never been expanded, even if the - original node was expanded already. */ - if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3)) - { - TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3); - TREE_OPERAND (*tp, 3) = NULL_TREE; - } - else if (TREE_CODE (*tp) == MODIFY_EXPR - && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1) - && ((*lang_hooks.tree_inlining.auto_var_in_fn_p) - (TREE_OPERAND (*tp, 0), fn))) + if (TREE_CODE (*tp) == MODIFY_EXPR + && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1) + && ((*lang_hooks.tree_inlining.auto_var_in_fn_p) + (TREE_OPERAND (*tp, 0), fn))) { /* Some assignments VAR = VAR; don't generate any rtl code and thus don't count as variable modification. Avoid @@ -572,9 +563,43 @@ copy_body_r (tp, walk_subtrees, data) value = (tree) n->value; STRIP_TYPE_NOPS (value); if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value)) - *tp = value; + { + *tp = value; + return copy_body_r (tp, walk_subtrees, data); + } } } + else if (TREE_CODE (*tp) == ADDR_EXPR + && ((*lang_hooks.tree_inlining.auto_var_in_fn_p) + (TREE_OPERAND (*tp, 0), fn))) + { + /* Get rid of &* from inline substitutions. It can occur when + someone takes the address of a parm or return slot passed by + invisible reference. */ + tree decl = TREE_OPERAND (*tp, 0), value; + splay_tree_node n; + + n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl); + if (n) + { + value = (tree) n->value; + if (TREE_CODE (value) == INDIRECT_REF) + { + *tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0)); + return copy_body_r (tp, walk_subtrees, data); + } + } + } + + copy_tree_r (tp, walk_subtrees, NULL); + + /* The copied TARGET_EXPR has never been expanded, even if the + original node was expanded already. */ + if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3)) + { + TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3); + TREE_OPERAND (*tp, 3) = NULL_TREE; + } } /* Keep iterating. */ |