On Mon, Oct 27, 2008 at 5:57 PM, Peter A. Felvegi <[EMAIL PROTECTED]> wrote: > Hello all, > > I've run today into an infinite loop when compiled a test suite w/ > optimizations. The original tests were to do some loops with all the > nonnegative values of some integral types. Instead of hardwiring the max > values, I thought testing for overflow into the negative domain is ok. > > Here is the source to reproduce the bug: > > ----8<----8<----8<----8<---- > #include <stdint.h> > #include <stdio.h> > > int f(int(*ff)(int)) > { > int8_t i = 0; /* the real loop counter */ > int ii = 0; /* loop counter for the test */ > do { > if (ff(ii)) { /* test ii through a fn ptr call */ > printf("ouch!\n"); /* too many loops */ > return ii; > } > ++ii; > } while (++i > 0); > /* > * the loop should stop when i overflows from 0x7f to > * 0x80 (ie -128) : 128 iterations > * if optimizations are enabled, it won't stop. > */ > return 0; > } > > extern int g_tr; > > int foo(int i) > { > return i > g_tr; > } > > int main(void) > { > f(&foo); > > return 0; > } > > int g_tr = 0x200; > ----8<----8<----8<----8<---- > > The call through the function pointer to test the loop counter is only for > disabling inlining. If i put everything into f(), it just prints "ouch" and > returns 0x201, the loop is optimized away completely. > > The expected behaviour is present (stopping after 128 iterations) if > compiled w/ -O0 or -O1, however, -O2 and above, and -Os result in an > infinite loop. > > The disassembly has an unconditional jump instruction after incrementing the > loop counter. > > Tested on: Debian Lenny (i386 and amd64), gcc 4.1, 4.2 and 4.3. > > Compile as: > $ gcc -g -O2 t.c > > then run as > $ ./a.out > > Is the above code considered illegal, or is it an issue with the optimizer
It's illegal. Signed overflow is undefined. if you want to guarantee wraparound, use -fwrapv or unsigned math.