Created attachment 23336 [details] preprocessor output gcc version 4.3.3 [gcc-4_3-branch revision 147732] (SUSE Linux) Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.3 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.3 --enable-linux-futex --without-system-libunwind --with-cpu=generic --build=x86_64-suse-linux COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O2' '-mtune=generic' /usr/lib64/gcc/x86_64-suse-linux/4.3/cc1 -E -quiet -v verify_counter_nonzero.c -mtune=generic -O2 -fpch-preprocess -o verify_counter_nonzero.i A local counter (named lCounter) is decremented in a while-loop, and the loop must stop when the counter reaches zero. In the same loop, a second local counter (lVeryHighCounter) is incremented and overflows in the same cycle where the first counter reaches zero. The overflow of the second counter seems to trigger that it is not detected that the first counter reaches zero: (lCounter != 0) remains false. A static counter (named sCounter) is used to observe what happens and to stop the program as soon as the bug is observed. The used -O2 option is needed to reproduce the bug. Using -O1 or -O3 does not reproduce the bug. extern int printf(const char *, ...); extern void exit(int); static int sCounter = 3; void verify_counter_nonzero( int aDummy ) { printf("sCounter value: %d\n", sCounter); if (sCounter == 0) { printf("Compiler bug detected! This function should not be called when counter reached 0.\n"); exit(0); } } int main() { int lCounter = 3; int lVeryHighCounter = 0x80000000 - 3; while (lCounter != 0) { verify_counter_nonzero(lVeryHighCounter); sCounter -= 1; lCounter -= 1; lVeryHighCounter += 1; /* In the same cycle where lCounter is decremented to 0, lVeryHighCounter is incremented (and overflows) from 0x7FFFFFFF to 0x80000000. This seems to trigger the bug: the loop condition (lCounter != 0) should become false, but remains true. */ } printf("Compiler bug not detected! Loop terminated correctly.\n"); }
"lVeryHighCounter is incremented (and overflows) from 0x7FFFFFFF to 0x80000000." And overflow is undefined in C/C++ so you are invoking undefined behavior here.
(In reply to comment #1) > And overflow is undefined in C/C++ so you are invoking undefined behavior here. Wow! This is an eye-opener for me! I am quite accustomed to assume two's complement arithmetic with implicit wrap-around for signed integers. After your remark I googled a bit and found several articles about undefined behavior, e.g. John Regehr's "A Guide to Undefined Behavior in C and C++, Part 1". Very instructive.