re PR middle-end/41317 (folding causes strict aliasing violation)
authorRichard Guenther <rguenther@suse.de>
Wed, 9 Sep 2009 14:35:51 +0000 (14:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 9 Sep 2009 14:35:51 +0000 (14:35 +0000)
2009-09-09  Richard Guenther  <rguenther@suse.de>

PR middle-end/41317
* tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Remove
code dealing with plain pointer bases.
(maybe_fold_offset_to_reference): Likewise.
(maybe_fold_stmt_addition): Adjust.

* gcc.c-torture/execute/pr41317.c: New testcase.
* gcc.dg/tree-ssa/forwprop-11.c: XFAIL.
* gcc.dg/tree-ssa/forwprop-12.c: Likewise.

From-SVN: r151559

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr41317.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c
gcc/tree-ssa-ccp.c

index e6f096a..f423067 100644 (file)
@@ -1,5 +1,13 @@
 2009-09-09  Richard Guenther  <rguenther@suse.de>
 
+       PR middle-end/41317
+       * tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Remove
+       code dealing with plain pointer bases.
+       (maybe_fold_offset_to_reference): Likewise.
+       (maybe_fold_stmt_addition): Adjust.
+
+2009-09-09  Richard Guenther  <rguenther@suse.de>
+
        * tree.c (free_lang_data_in_type): Do not free the type variant
        chains.
        (free_lang_data): Merge char_type_node with its properly signed
index 229c800..7b17043 100644 (file)
@@ -1,3 +1,10 @@
+2009-09-09  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41317
+       * gcc.c-torture/execute/pr41317.c: New testcase.
+       * gcc.dg/tree-ssa/forwprop-11.c: XFAIL.
+       * gcc.dg/tree-ssa/forwprop-12.c: Likewise.
+
 2009-09-08  Dodji Seketeli  <dodji@redhat.com>
 
        Fix some test breakages on Darwin
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41317.c b/gcc/testsuite/gcc.c-torture/execute/pr41317.c
new file mode 100644 (file)
index 0000000..742068b
--- /dev/null
@@ -0,0 +1,28 @@
+extern void abort (void);
+
+struct A
+{
+  int i;
+};
+struct B
+{
+  struct A a;
+  int j;
+};
+
+static void
+foo (struct B *p)
+{
+  ((struct A *)p)->i = 1;
+}
+
+int main()
+{
+  struct A a;
+  a.i = 0;
+  foo ((struct B *)&a);
+  if (a.i != 1)
+    abort ();
+  return 0;
+}
+
index eaaa6dd..73051ae 100644 (file)
@@ -15,5 +15,5 @@ int g(int *p, int n)
   return q[-1];
 }
 
-/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump "forwprop1" } } */
index a74809b..1c5ea02 100644 (file)
@@ -18,5 +18,5 @@ int bar(struct X *p, int i)
 /* We should have propagated the base array address through the
    address arithmetic into the memory access as an array access.  */
 
-/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump "forwprop1" } } */
index 14ffdfe..61827a7 100644 (file)
@@ -1818,8 +1818,7 @@ maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset,
 
 static tree
 maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
-                                   tree base, tree offset,
-                                   tree orig_type, bool base_is_ptr)
+                                   tree base, tree offset, tree orig_type)
 {
   tree f, t, field_type, tail_array_field, field_offset;
   tree ret;
@@ -1871,8 +1870,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
       if (cmp == 0
          && useless_type_conversion_p (orig_type, field_type))
        {
-         if (base_is_ptr)
-           base = build1 (INDIRECT_REF, record_type, base);
          t = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
          return t;
        }
@@ -1897,13 +1894,8 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
 
       /* If we matched, then set offset to the displacement into
         this field.  */
-      if (base_is_ptr)
-       new_base = build1 (INDIRECT_REF, record_type, base);
-      else
-       new_base = base;
-      protected_set_expr_location (new_base, loc);
-      new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE);
-      protected_set_expr_location (new_base, loc);
+      new_base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
+      SET_EXPR_LOCATION (new_base, loc);
 
       /* Recurse to possibly find the match.  */
       ret = maybe_fold_offset_to_array_ref (loc, new_base, t, orig_type,
@@ -1911,7 +1903,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
       if (ret)
        return ret;
       ret = maybe_fold_offset_to_component_ref (loc, field_type, new_base, t,
-                                               orig_type, false);
+                                               orig_type);
       if (ret)
        return ret;
     }
@@ -1925,11 +1917,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
 
   /* If we get here, we've got an aggregate field, and a possibly 
      nonzero offset into them.  Recurse and hope for a valid match.  */
-  if (base_is_ptr)
-    {
-      base = build1 (INDIRECT_REF, record_type, base);
-      SET_EXPR_LOCATION (base, loc);
-    }
   base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
   SET_EXPR_LOCATION (base, loc);
 
@@ -1938,7 +1925,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
   if (t)
     return t;
   return maybe_fold_offset_to_component_ref (loc, field_type, base, offset,
-                                            orig_type, false);
+                                            orig_type);
 }
 
 /* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE->field_of_orig_type
@@ -1955,61 +1942,44 @@ maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
 {
   tree ret;
   tree type;
-  bool base_is_ptr = true;
 
   STRIP_NOPS (base);
-  if (TREE_CODE (base) == ADDR_EXPR)
-    {
-      base_is_ptr = false;
-
-      base = TREE_OPERAND (base, 0);
+  if (TREE_CODE (base) != ADDR_EXPR)
+    return NULL_TREE;
 
-      /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union,
-        so it needs to be removed and new COMPONENT_REF constructed.
-        The wrong COMPONENT_REF are often constructed by folding the
-        (type *)&object within the expression (type *)&object+offset  */
-      if (handled_component_p (base))
+  base = TREE_OPERAND (base, 0);
+
+  /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union,
+     so it needs to be removed and new COMPONENT_REF constructed.
+     The wrong COMPONENT_REF are often constructed by folding the
+     (type *)&object within the expression (type *)&object+offset  */
+  if (handled_component_p (base))
+    {
+      HOST_WIDE_INT sub_offset, size, maxsize;
+      tree newbase;
+      newbase = get_ref_base_and_extent (base, &sub_offset,
+                                        &size, &maxsize);
+      gcc_assert (newbase);
+      if (size == maxsize
+         && size != -1
+         && !(sub_offset & (BITS_PER_UNIT - 1)))
        {
-          HOST_WIDE_INT sub_offset, size, maxsize;
-         tree newbase;
-         newbase = get_ref_base_and_extent (base, &sub_offset,
-                                            &size, &maxsize);
-         gcc_assert (newbase);
-         if (size == maxsize
-             && size != -1
-             && !(sub_offset & (BITS_PER_UNIT - 1)))
-           {
-             base = newbase;
-             if (sub_offset)
-               offset = int_const_binop (PLUS_EXPR, offset,
-                                         build_int_cst (TREE_TYPE (offset),
-                                         sub_offset / BITS_PER_UNIT), 1);
-           }
+         base = newbase;
+         if (sub_offset)
+           offset = int_const_binop (PLUS_EXPR, offset,
+                                     build_int_cst (TREE_TYPE (offset),
+                                                    sub_offset / BITS_PER_UNIT), 1);
        }
-      if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
-         && integer_zerop (offset))
-       return base;
-      type = TREE_TYPE (base);
     }
-  else
-    {
-      base_is_ptr = true;
-      if (!POINTER_TYPE_P (TREE_TYPE (base)))
-       return NULL_TREE;
-      type = TREE_TYPE (TREE_TYPE (base));
-    }
-  ret = maybe_fold_offset_to_component_ref (loc, type, base, offset,
-                                           orig_type, base_is_ptr);
+  if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
+      && integer_zerop (offset))
+    return base;
+  type = TREE_TYPE (base);
+
+  ret = maybe_fold_offset_to_component_ref (loc, type, base, offset, orig_type);
   if (!ret)
-    {
-      if (base_is_ptr)
-       {
-         base = build1 (INDIRECT_REF, type, base);
-         SET_EXPR_LOCATION (base, loc);
-       }
-      ret = maybe_fold_offset_to_array_ref (loc,
-                                           base, offset, orig_type, true);
-    }
+    ret = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type, true);
+
   return ret;
 }
 
@@ -2286,7 +2256,7 @@ maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1)
   t = maybe_fold_offset_to_array_ref (loc, op0, op1, ptd_type, true);
   if (!t)
     t = maybe_fold_offset_to_component_ref (loc, TREE_TYPE (op0), op0, op1,
-                                           ptd_type, false);
+                                           ptd_type);
   if (t)
     {
       t = build1 (ADDR_EXPR, res_type, t);