The testcase below fails: 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; } on arm targets with optimisation. At -O0 it doesn't abort. The wrong code is at statement: struct S e = c[0]; The constructor initialisation RTL emitted is: ;; e = c[0]; (insn 5 4 6 (set (reg/v:SI 112 [ e ]) (const_int 0 [0])) (nil)) (insn 6 5 7 (set (reg/v:SI 112 [ e ]) (const_int -1 [0xffffffffffffffff])) (nil)) The second SET clobbers the whole word rather than just the 16 bits it was supposed to. The problem is in store_constructor in expr.c where it widens the first store to word mode by sign-extending the value but then tries to avoid storing the zero bitfield because it had initially cleared out the word (the first set). This testcase works for me for GCC 4.8.5 but fails on 4.9 and later
I'm testing a patch
Author: ktkachov Date: Tue Jul 12 15:00:28 2016 New Revision: 238248 URL: https://gcc.gnu.org/viewcvs?rev=238248&root=gcc&view=rev Log: [expr.c] PR middle-end/71700: zero-extend sub-word value when widening constructor element 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.c-torture/execute/pr71700.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr71700.c Modified: trunk/gcc/ChangeLog trunk/gcc/expr.c trunk/gcc/testsuite/ChangeLog
Fixed for GCC 7. Will test backports
GCC 4.9 branch is being closed
Author: ktkachov Date: Mon Aug 22 14:28:05 2016 New Revision: 239660 URL: https://gcc.gnu.org/viewcvs?rev=239660&root=gcc&view=rev Log: [expr.c] PR middle-end/71700: zero-extend sub-word value when widening constructor element Backport from mainline 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.c-torture/execute/pr71700.c: New test. Added: branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/execute/pr71700.c Modified: branches/gcc-6-branch/gcc/ChangeLog branches/gcc-6-branch/gcc/expr.c branches/gcc-6-branch/gcc/testsuite/ChangeLog
Author: ktkachov Date: Thu Aug 25 09:26:15 2016 New Revision: 239754 URL: https://gcc.gnu.org/viewcvs?rev=239754&root=gcc&view=rev Log: [expr.c] PR middle-end/71700: zero-extend sub-word value when widening constructor element Backport from mainline 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.c-torture/execute/pr71700.c: New test. Added: branches/gcc-5-branch/gcc/testsuite/gcc.c-torture/execute/pr71700.c Modified: branches/gcc-5-branch/gcc/ChangeLog branches/gcc-5-branch/gcc/expr.c branches/gcc-5-branch/gcc/testsuite/ChangeLog
Fixed for 5.5, 6.3, 7.0