tree-inline.c (copy_body_r): Avoid generating &* during inline substitution.
authorJason Merrill <jason@redhat.com>
Mon, 19 May 2003 16:17:32 +0000 (12:17 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 19 May 2003 16:17:32 +0000 (12:17 -0400)
        * tree-inline.c (copy_body_r): Avoid generating &* during inline
        substitution.

From-SVN: r66964

gcc/ChangeLog
gcc/tree-inline.c

index b4aeb336269aa26b2bcc545b18e616a0ad85ff62..066c27330f25d216998d6656b1ad009efc595400 100644 (file)
@@ -1,3 +1,8 @@
+2003-05-19  Jason Merrill  <jason@redhat.com>
+
+       * tree-inline.c (copy_body_r): Avoid generating &* during inline
+       substitution.
+
 2003-05-19  Andrew Macleod  <amacleod@redhat.com>
 
        * config/stormy16/stormy16.c (xstormy16_expand_prologue): Do
index d2cf66a364c9d383ed955391307cfe7514fc24be..1387b9960db5e1591debbe31cbf0b044afe07448 100644 (file)
@@ -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.  */