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.)
The C standard requirements that certain source code has certain semantics (such as, in this case, overflows making something not an integer constant expression and so an array a VLA) are unchanged by -fwrapv; that simply concerns what happens for certain code that under standard C would be undefined at runtime. The diagnostic is correct and probably occurs as a result of fixes for various internal compiler errors relating to expressions with integer operands that are not integer constant expressions. However, it might be possible to downgrade it to a pedwarn the way it is already downgraded for some other expressions folding to an integer constant.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.