2005-07-26 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jul 2005 07:34:58 +0000 (07:34 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jul 2005 07:34:58 +0000 (07:34 +0000)
PR tree-optimization/22486
* fold-const.c (fold_unary): Fold away useless component
references of the form (T *)&T.x, if the address
doesn't change.

* gcc.dg/tree-ssa/upcast-1.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102381 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c [new file with mode: 0644]

index b3bf9d2..315a636 100644 (file)
@@ -1,3 +1,10 @@
+2005-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/22486
+       * fold-const.c (fold_unary): Fold away useless component
+       references of the form (T *)&T.x, if the address
+       doesn't change.
+
 2005-07-25  James E Wilson  <wilson@specifixinc.com>
 
        * dwarf2out.c (add_call_src_coords_attributes): New.
index 9a9ea22..bdda600 100644 (file)
@@ -6711,6 +6711,29 @@ fold_unary (enum tree_code code, tree type, tree op0)
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
        }
 
+      /* Handle (T *)&A.B.C for A being of type T and B and C
+        living at offset zero.  This occours frequently in
+        C++ upcasting and then accessing the base.  */
+      if (TREE_CODE (op0) == ADDR_EXPR
+         && POINTER_TYPE_P (type)
+         && handled_component_p (TREE_OPERAND (op0, 0)))
+        {
+         HOST_WIDE_INT bitsize, bitpos;
+         tree offset;
+         enum machine_mode mode;
+         int unsignedp, volatilep;
+          tree base = TREE_OPERAND (op0, 0);
+         base = get_inner_reference (base, &bitsize, &bitpos, &offset,
+                                     &mode, &unsignedp, &volatilep, false);
+         /* If the reference was to a (constant) zero offset, we can use
+            the address of the base if it has the same base type
+            as the result type.  */
+         if (! offset && bitpos == 0
+             && TYPE_MAIN_VARIANT (TREE_TYPE (type))
+                 == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
+           return fold_convert (type, build_fold_addr_expr (base));
+        }
+
       if (TREE_CODE (op0) == MODIFY_EXPR
          && TREE_CONSTANT (TREE_OPERAND (op0, 1))
          /* Detect assigning a bitfield.  */
index f82d239..693ddc9 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/22486
+       * gcc.dg/tree-ssa/upcast-1.c: New testcase.
+
 2005-07-25  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR tree-opt/22484
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c b/gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c
new file mode 100644 (file)
index 0000000..12c2b91
--- /dev/null
@@ -0,0 +1,12 @@
+/* { do-go compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+typedef struct { int i; } Foo;
+Foo foo;
+Foo *bar(void)
+{
+  return (Foo *)&foo.i;
+}
+
+/* { dg-final { scan-tree-dump "&foo;" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */