gcc/
authorYvan Roux <yvan.roux@linaro.org>
Mon, 5 Sep 2016 17:02:37 +0000 (19:02 +0200)
committerYvan Roux <yvan.roux@linaro.org>
Wed, 7 Sep 2016 20:08:54 +0000 (22:08 +0200)
Backport from trunk r238248.
2016-07-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

PR middle-end/71700
* expr.c (store_constructor): Mask sign-extended bits when widening
sub-word constructor element at the start of a word.

gcc/testsuite/
Backport from trunk r238248.
2016-07-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

PR middle-end/71700
* gcc.c-torture/execute/pr71700.c: New test.

Change-Id: Ib37452367e4ec169ca88ada2d233bc6a608c1045

gcc/expr.c
gcc/testsuite/gcc.c-torture/execute/pr71700.c [new file with mode: 0644]

index 29d22b0..eb77ba0 100644 (file)
@@ -6139,6 +6139,13 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size,
                    type = lang_hooks.types.type_for_mode
                      (word_mode, TYPE_UNSIGNED (type));
                    value = fold_convert (type, value);
+                   /* Make sure the bits beyond the original bitsize are zero
+                      so that we can correctly avoid extra zeroing stores in
+                      later constructor elements.  */
+                   tree bitsize_mask
+                     = wide_int_to_tree (type, wi::mask (bitsize, false,
+                                                          BITS_PER_WORD));
+                   value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
                  }
 
                if (BYTES_BIG_ENDIAN)
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71700.c b/gcc/testsuite/gcc.c-torture/execute/pr71700.c
new file mode 100644 (file)
index 0000000..80afd38
--- /dev/null
@@ -0,0 +1,19 @@
+struct S
+{
+  signed f0 : 16;
+  unsigned f1 : 1;
+};
+
+int b;
+static struct S c[] = {{-1, 0}, {-1, 0}};
+struct S d;
+
+int
+main ()
+{
+  struct S e = c[0];
+  d = e;
+  if (d.f1 != 0)
+    __builtin_abort ();
+  return 0;
+}