Hi, playing with testcases for path isolation and const function, I noticed that we do not seem to even try to isolate out of range array accesses: int a[3]={0,1,2}; test(int i) { if (i > 3) return test2(a[i]); return a[i]; }
Here call to test2 is dead, since a[i] will access memory past of the array. We produce a warning: t.c:5:24: warning: array subscript 4 is above array bounds of ‘int[3]’ [-Warray-bounds=] but we still keep the call: test: .LFB0: .cfi_startproc movslq %edi, %rax movl a(,%rax,4), %eax cmpl $3, %edi jg .L4 ret .p2align 4,,10 .p2align 3 .L4: movl %eax, %edi xorl %eax, %eax jmp test2 We eventually move the load before conditional, but at path isolation time it is still quite obvious the conditional being true invokes undefined behaviour int test (int i) { int _1; int _2; int _6; int _8; <bb 2> [local count: 1073741824]: if (i_4(D) > 3) goto <bb 3>; [20.24%] else goto <bb 4>; [79.76%] <bb 3> [local count: 217325344]: _1 = a[i_4(D)]; _8 = test2 (_1); goto <bb 5>; [100.00%] <bb 4> [local count: 856416481]: _6 = a[i_4(D)]; <bb 5> [local count: 1073741824]: # _2 = PHI <_8(3), _6(4)> return _2; } Curiously adjusting the testcase: const int a[3]={0,1,2}; test(int i) { if (i == 3) return test2(a[i]); return a[i]; } no longer has undefined behaviour visible at isolate-paths int test (int i) { int _1; int _5; int _7; <bb 2> [local count: 1073741824]: if (i_3(D) == 3) goto <bb 3>; [11.56%] else goto <bb 4>; [88.44%] <bb 3> [local count: 124124552]: _7 = test2 (0); goto <bb 5>; [100.00%] <bb 4> [local count: 949617273]: _5 = a[i_3(D)]; <bb 5> [local count: 1073741824]: # _1 = PHI <_7(3), _5(4)> return _1; } since we fold the load to 0. It would perhaps help optimizers to keep info on undefined behaviour happening there. Honza