http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55009
Bug #: 55009 Summary: compile-time assertions no longer usable: error: variably modified ‘ari_sign_32_bit_and_wrap’ at file scope Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: t...@mirbsd.org Hi everyone, I’ve been using compile-time assertions, that is, compiling .c files with arrays that are either 1 or -1 bytes long, depending on some assertion, for a while now, and one of these now no longer works: the check whether a certain integer type is 32-bit with usable wraparound, as asked for by -fwrapv. (I need to check this because the program in question is a shell that guarantees this behaviour to scripts run in it, even for signed integers, and recent GCC versions are known to optimise the wraparound away, as it’s UD, strictly spoken, but can be made to work.) This affects recent gcc-4.6 and gcc-4.7 uploads into Debian and Ubuntu, at least, as well as gcc trunk: tg@zigo:~ $ /usr/lib/gcc-snapshot/bin/gcc -v Using built-in specs. COLLECT_GCC=/usr/lib/gcc-snapshot/bin/gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-snapshot/libexec/gcc/x86_64-linux-gnu/4.8.0/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 20121008-1' --with-bugurl=file:///usr/share/doc/gcc-snapshot/README.Bugs --enable-languages=c,ada,c++,java,go,fortran,objc,obj-c++ --prefix=/usr/lib/gcc-snapshot --enable-shared --enable-linker-build-id --with-system-zlib --disable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-snap/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-snap --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-snap --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --with-arch-32=i586 --with-tune=generic --disable-werror --enable-checking=yes --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.0 20121008 (experimental) [trunk revision 192192] (Debian 20121008-1) tg@zigo:~ $ cat t.c #include <stdint.h> typedef int32_t mksh_ari_t; char ari_sign_32_bit_and_wrap[( (mksh_ari_t)(((((mksh_ari_t)1 << 15) << 15) - 1) * 2 + 1) > (mksh_ari_t)(((((mksh_ari_t)1 << 15) << 15) - 1) * 2 + 2) ) ? 1 : -1]; int main(void) { return (sizeof(ari_sign_32_bit_and_wrap)); } tg@zigo:~ $ if /usr/lib/gcc-snapshot/bin/gcc -O t.c; then ./a.out; echo ok $?; else echo error $?; fi t.c:6:62: warning: integer overflow in expression [-Woverflow] (mksh_ari_t)(((((mksh_ari_t)1 << 15) << 15) - 1) * 2 + 2) ^ t.c:3:6: error: variably modified 'ari_sign_32_bit_and_wrap' at file scope char ari_sign_32_bit_and_wrap[( ^ error 1 tg@zigo:~ $ gcc-4.7 -v Using built-in specs. COLLECT_GCC=/usr/bin/gcc-4.7.real COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-2' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.7.2 (Debian 4.7.2-2) tg@zigo:~ $ if gcc-4.7 -O t.c; then ./a.out; echo ok $?; else echo error $?; fi t.c:6:62: warning: integer overflow in expression [-Woverflow] t.c:3:6: error: variably modified ‘ari_sign_32_bit_and_wrap’ at file scope error 1 tg@zigo:~ $ gcc-4.6 -v Using built-in specs. COLLECT_GCC=/usr/bin/gcc-4.6.real COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.3-10' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.6.3 (Debian 4.6.3-10) tg@zigo:~ $ if gcc-4.6 -O t.c; then ./a.out; echo ok $?; else echo error $?; fi t.c:6:62: warning: integer overflow in expression [-Woverflow] t.c:3:6: error: variably modified ‘ari_sign_32_bit_and_wrap’ at file scope error 1 This used to be no problem (though gcc did warn about the overflow despite passing -fwrapv). Swapping out the cc1 binary with a slightly older version confirms that this is a recent development localised to that. I’m reporting this here by request of the Debian GCC Maintainers to decide whether this is, indeed, a bug in GCC, or whether applications cannot use this kind of compile-time check any more, in which case I would be _really_ thankful if someone can point me out a way to check for the integer size and wraparound. (Note that the unsigned version of the check passes with no issue.)