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?
Regards, Peter