aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expr.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr71700.c19
4 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 509e855..ac411d5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2016-07-12 Martin Liska <mliska@suse.cz>
* ira-build.c (mark_loops_for_removal): Properly iterate
diff --git a/gcc/expr.c b/gcc/expr.c
index fbc91ad..4073a98 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6281,6 +6281,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/ChangeLog b/gcc/testsuite/ChangeLog
index 7dd3c92..71b5227 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR middle-end/71700
+ * gcc.c-torture/execute/pr71700.c: New test.
+
2016-07-12 Steven Bosscher <steven@gcc.gnu.org>
Richard Biener <rguenther@suse.de>
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71700.c b/gcc/testsuite/gcc.c-torture/execute/pr71700.c
new file mode 100644
index 0000000..80afd38
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr71700.c
@@ -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;
+}