This has been tested on 3.3.6, 3.4.1 and 4.0.1 The following test is considered always false and the block is dropped but "a" being "int", (a + 1 < 0) is true. [pterjan@plop tmp]$ cat lim.c #include <stdio.h> #include <limits.h> int main (void) { int a = INT_MAX; if ((a < 0) || (a + 1 < 0)) { printf("Hello !\n"); } return 0; } [pterjan@plop tmp]$ gcc -O0 lim.c ; ./a.out Hello ! [pterjan@plop tmp]$ gcc -O1 lim.c ; ./a.out [pterjan@plop tmp]$
Note signed overflow is undefined unless you use -fwrapv except that does not fix this. This is a bug in fold, most likely build_range_check.
Here is a java program (since -fwrapv is turned on by default for java front-end unlike the C front-end since it is undefined in C and defined in java): class t { public static void main(String as[]) { int a; a = Integer.MAX_VALUE; if ((a < 0) || (a + 1 < 0)) { System.out.println("Hello"); } } }
fold_range_test is wrong, around fold-const.c:4635
I've got a patch.
Subject: Bug 23518 Author: kazu Date: Thu Dec 22 04:03:32 2005 New Revision: 108940 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=108940 Log: gcc/ PR tree-optimization/23518 * fold-const.c (make_range): Don't move a constant to the other side of the comparison if the type is signed and -fwrapv is given. gcc/testsuite/ PR tree-optimization/23518 * testsuite/gcc.dg/pr23518.c: New. Added: trunk/gcc/testsuite/gcc.dg/pr23518.c Modified: trunk/gcc/ChangeLog trunk/gcc/fold-const.c trunk/gcc/testsuite/ChangeLog
Just checked in a patch.
Oops, I forgot to change resolution to FIXED.