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

Reply via email to