gcc creates invalid code for ------ struct snd_mask { unsigned int bits[6]; // ****** (1) ******* };
static int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v) { struct snd_mask old; old = *mask; if (mask->bits[0]==0 && mask->bits[1]==0) *(char *)0 = 0; return mask->bits[0] == old.bits[0] ? 0 : 1; } static int test(struct snd_mask *a, struct snd_mask *b) { return snd_mask_refine(a, b); } int main(int argc, char *argv[]) { int volatile v = 0; struct snd_mask mask; struct snd_mask m; mask.bits[0] = 23; mask.bits[1] = 42; mask.bits[2] = 0; mask.bits[3] = 0; mask.bits[4] = 0; // ****** (2) ******** mask.bits[5] = 0; m.bits[0] = 0xffffffff; m.bits[1] = 0xffffffff; m.bits[2] = 0xffffffff; m.bits[3] = 0xffffffff; m.bits[4] = 0xffffffff; m.bits[5] = 0xffffffff; return !v ? test(&mask, &m) : test(&m, &mask); } ------ | $ arm-xscale-linux-gnu-gcc -Os ./test.c | $ ./a.out | Segmentation fault When changing parameters things are fine; e.g. | $ arm-xscale-linux-gnu-gcc -O0 ./test.c | $ ./a.out | $ Affecting parameters are: * assigning '1' instead of '0' at (2) * the array size at (1); e.g. 5 instead of 6 makes it work as expected * optimization flags; e.g. '-O0' or '-O3' makes it work * platform; can not reproduce it on non-arm compilers, The code gnerated by '-Os' is | 000080a0 <test>: | 80a0: e52de004 str lr, [sp, #-4]! | 80a4: e24dd018 sub sp, sp, #24 ; 0x18 | 80a8: e1a0c00d mov ip, sp | 80ac: e1a0e000 mov lr, r0 | 80b0: e8be000f ldmia lr!, {r0, r1, r2, r3} | 80b4: e8ac000f stmia ip!, {r0, r1, r2, r3} | 80b8: e89e0003 ldmia lr, {r0, r1} | 80bc: e2503000 subs r3, r0, #0 ; 0x0 | 80c0: e88c0003 stmia ip, {r0, r1} | 80c4: e59d2000 ldr r2, [sp] | 80c8: 1a000001 bne 80d4 <test+0x34> | 80cc: e3510000 cmp r1, #0 ; 0x0 | 80d0: 05c33000 streqb r3, [r3] | 80d4: e0530002 subs r0, r3, r2 | 80d8: 13a00001 movne r0, #1 ; 0x1 | 80dc: e28dd018 add sp, sp, #24 ; 0x18 | 80e0: e8bd8000 ldmia sp!, {pc} afais: * 0x80b0 + 0x80b4 copies 'mask[0..3]' to 'old[0..3]'. * 0x80b8 loads mask[4..5] into {r0,r1} * now, it uses r0 which contains mask[4] but not mask[0] for comparision which is wrong Bug can be reproduced with $ $C-gcc-3.4.5 -v Reading specs from /usr/lib/gcc/arm-xscale-linux-gnu/3.4.5/specs Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu --host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu --with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit --enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info --mandir=/usr/share/man --enable-version-specific-runtime-libs --enable-languages=c,c++ --enable-shared --enable-threads --disable-multilib --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer Thread model: posix gcc version 3.4.5 $ $C-gcc-4.0.3 -v Using built-in specs. Target: arm-xscale-linux-gnu Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu --host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu --with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit --enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info --mandir=/usr/share/man --enable-version-specific-runtime-libs --enable-languages=c --enable-shared --enable-threads --disable-multilib --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer Thread model: posix gcc version 4.0.3 $ $C-gcc-4.1.1 -v Using built-in specs. Target: arm-xscale-linux-gnu Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu --host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu --with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit --enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info --mandir=/usr/share/man --enable-version-specific-runtime-libs --disable-multilib --enable-languages=c,c++,java,objc --enable-shared --enable-threads --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer Thread model: posix gcc version 4.1.1 The assembler code above was created with 4.1.1. I think this is a major bug. -- Summary: Invalid code e.g. for ALSA kernel driver Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: enrico dot scholz at informatik dot tu-chemnitz dot de GCC build triplet: i386-redhat-linux GCC host triplet: i386-redhat-linux GCC target triplet: arm-xscale-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28362