aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-07-19 11:24:28 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-07-19 11:24:28 +0200
commitb8b2b0094a9047a1ad476d96f0d20d4b56fca625 (patch)
tree9ebdcc8fe15b0de1cd9d54526c0832bc2573669e
parent338f655dae09fc11f3fa4bc693360d93d9e72bb6 (diff)
downloadgcc-b8b2b0094a9047a1ad476d96f0d20d4b56fca625.zip
gcc-b8b2b0094a9047a1ad476d96f0d20d4b56fca625.tar.gz
gcc-b8b2b0094a9047a1ad476d96f0d20d4b56fca625.tar.bz2
re PR tree-optimization/49768 (C99 style union initializations does not work as expected with optimizations)
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimple-fold.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr49768.c12
4 files changed, 33 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62293be..d46d52d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index bf00a0f..d1c5c89 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ffc6f0b..07c283d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..85bc9d2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr49768.c
@@ -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;
+}