From bf9f6b2f3c95f0d6814d5a0b9eb07bac263f62a7 Mon Sep 17 00:00:00 2001 From: Yvan Roux Date: Mon, 5 Sep 2016 19:02:37 +0200 Subject: [PATCH] gcc/ Backport from trunk r238248. 2016-07-12 Kyrylo Tkachov 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 PR middle-end/71700 * gcc.c-torture/execute/pr71700.c: New test. Change-Id: Ib37452367e4ec169ca88ada2d233bc6a608c1045 --- gcc/expr.c | 7 +++++++ gcc/testsuite/gcc.c-torture/execute/pr71700.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr71700.c diff --git a/gcc/expr.c b/gcc/expr.c index 29d22b0..eb77ba0 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 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; +} -- 2.7.4