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++; }