re PR tree-optimization/49768 (C99 style union initializations does not work as expec...
authorJakub Jelinek <jakub@redhat.com>
Tue, 19 Jul 2011 09:24:28 +0000 (11:24 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 19 Jul 2011 09:24:28 +0000 (11:24 +0200)
PR tree-optimization/49768
* gimple-fold.c (fold_nonarray_ctor_reference): Return NULL
if offset is smaller than bitoffset, but offset+size is bigger
than bitoffset.

* gcc.c-torture/execute/pr49768.c: New test.

From-SVN: r176437

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr49768.c [new file with mode: 0644]

index 62293beeaa1f8dcafe221dbd6c86402d6751137f..d46d52d2138698dac00a97ef75dd78a76b035d69 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/49768
+       * gimple-fold.c (fold_nonarray_ctor_reference): Return NULL
+       if offset is smaller than bitoffset, but offset+size is bigger
+       than bitoffset.
+
 2011-07-19  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/49771
index bf00a0f04604013a2c3205b04fd9b1bcf4f2993d..d1c5c89546ff797f51e82d6f6732e55e3017aebe 100644 (file)
@@ -3231,7 +3231,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
       double_int bitoffset;
       double_int byte_offset_cst = tree_to_double_int (byte_offset);
       double_int bits_per_unit_cst = uhwi_to_double_int (BITS_PER_UNIT);
-      double_int bitoffset_end;
+      double_int bitoffset_end, access_end;
 
       /* Variable sized objects in static constructors makes no sense,
         but field_size can be NULL for flexible array members.  */
@@ -3252,14 +3252,16 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
       else
        bitoffset_end = double_int_zero;
 
-      /* Is OFFSET in the range (BITOFFSET, BITOFFSET_END)?  */
-      if (double_int_cmp (uhwi_to_double_int (offset), bitoffset, 0) >= 0
+      access_end = double_int_add (uhwi_to_double_int (offset),
+                                  uhwi_to_double_int (size));
+
+      /* Is there any overlap between [OFFSET, OFFSET+SIZE) and
+        [BITOFFSET, BITOFFSET_END)?  */
+      if (double_int_cmp (access_end, bitoffset, 0) > 0
          && (field_size == NULL_TREE
              || double_int_cmp (uhwi_to_double_int (offset),
                                 bitoffset_end, 0) < 0))
        {
-         double_int access_end = double_int_add (uhwi_to_double_int (offset),
-                                                 uhwi_to_double_int (size));
          double_int inner_offset = double_int_sub (uhwi_to_double_int (offset),
                                                    bitoffset);
          /* We do have overlap.  Now see if field is large enough to
@@ -3267,6 +3269,8 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
             fields.  */
          if (double_int_cmp (access_end, bitoffset_end, 0) > 0)
            return NULL_TREE;
+         if (double_int_cmp (uhwi_to_double_int (offset), bitoffset, 0) < 0)
+           return NULL_TREE;
          return fold_ctor_reference (type, cval,
                                      double_int_to_uhwi (inner_offset), size);
        }
index ffc6f0baa7324304b9b531738bbfe97ce17a6971..07c283dcc0c2fd4ec5b796844fc951df6cdc3087 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/49768
+       * gcc.c-torture/execute/pr49768.c: New test.
+
 2011-07-19  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/49771
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr49768.c b/gcc/testsuite/gcc.c-torture/execute/pr49768.c
new file mode 100644 (file)
index 0000000..85bc9d2
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR tree-optimization/49768 */
+
+extern void abort (void);
+
+int
+main ()
+{
+  static struct { unsigned int : 1; unsigned int s : 1; } s = { .s = 1 };
+  if (s.s != 1)
+    abort ();
+  return 0;
+}