Bug 55009 - compile-time assertions no longer usable: error: variably modified ‘ari_sign_32_bit_and_wrap’ at file scope
Summary: compile-time assertions no longer usable: error: variably modified ‘ari_sign_...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-21 17:37 UTC by Thorsten Glaser
Modified: 2014-02-17 18:24 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thorsten Glaser 2012-10-21 17:37:18 UTC
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.)
Comment 1 joseph@codesourcery.com 2012-10-21 23:41:28 UTC
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.
Comment 2 Jackie Rosen 2014-02-16 13:16:15 UTC Comment hidden (spam)