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.

Reply via email to