https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98663

            Bug ID: 98663
           Summary: gcc generates endless loop at -O2 or greater depending
                    on order of testExpression
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: charliepdts at gmx dot at
  Target Milestone: ---

Created attachment 49961
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49961&action=edit
minimal example in testcase_bad_for

While porting legacy code which worked with v4.1.1 to v4.9.1 we discovered gcc
producing an endless loop.

Our v4.9.1 configured with: --enable-languages=c,c++ --with-float=soft
--enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp
--disable-libquadmath --disable-libquadmath-support --disable-libsanitizer
--with-gmp=... --with-mpfr=... --with-mpc=... --with-isl=... --with-cloog=...
--with-libelf=... --enable-threads=posix --disable-nls --disable-multilib
--enable-c99 --enable-long-long

gcc version: 
We also tried this on various linux distributions with gcc versions greater
v4.6.4 up to v9 and they all produced endless loops with this code.

gcc targets:
This appears independent of the target architecture as powerpc, arm and x86_64
targets all displayed the same behaviour.

Compilation options:
gcc -Wall -Wextra -Os -o test4 test4.c

Compilation output:
none

mini-snippet, test4.i included:
unsigned short read[450];
for (i = 0 ; (read[i] != 0xFFFF) && (i < 450) ; i++) {...}

The assembly code generated does the first check but optimises out the second. 

Now while I agree that the above code is not really nice (legacy...) with the
last loop check being an out of bounds read access, 'gcc -Wall -Wextra' does
not even produce an array bounds warning.

With -O1 correct code is produced, no array bounds warning though. 
With -O2 and -fno-aggressive-loop-optimizations correct code is produced.
Otherwise -O2, -Os and -O3 all produce endless loops.

turning the checks in the testExpression around as expected produces correct
code 
for (i = 0 ; (i < 450) && (read[i] != 0xFFFF) ; i++)

similar while loops produce the same endless loops
   while ((read[i] != 0xFFFF) && (i < 450))
      {
      ...
      i++;  
      }

Reply via email to