https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82177
Bug ID: 82177 Summary: Alias analysis too aggressive with integer-to-pointer cast Product: gcc Version: 7.2.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: nunoplopes at sapo dot pt CC: gil.hur at sf dot snu.ac.kr, jeehoon.kang at sf dot snu.ac.kr, regehr at cs dot utah.edu, sanjoy at playingwithpointers dot com Target Milestone: --- The following code gets miscompiled with gcc: #include <stdio.h> #include <stdint.h> void f(int*, int*); int main() { int a=0, y[1], x = 0; uintptr_t pi = (uintptr_t) &x; uintptr_t yi = (uintptr_t) (y+1); uintptr_t n = pi != yi; if (n) { a = 100; pi = yi; } if (n) { a = 100; pi = (uintptr_t) y; } *(int *)pi = 15; printf("a=%d x=%d\n", a, x); f(&x,y); return 0; } $ gcc -O2 c.c b.c -o foo $ ./foo a=0 x=0 This result is wrong. The two possible outcomes are: a=0 x=15, and a=100 x=0. The bug seems to be in the alias analysis, which is not conservative enough in handling integer-to-pointer casts. The wrong transformation happens at this point (dump with -fdump-tree-all): $ cat c.c.123t.pre yi_8 = { y } y = { ESCAPED NONLOCAL } pi_4 = { y } same as yi_8 pi_9 = { y } same as yi_8 pi.0_10 = { y } same as yi_8 (...) pi_7 = (uintptr_t) &x; yi_8 = (uintptr_t) &MEM[(void *)&y + 4B]; if (pi_7 != yi_8) goto <bb 4>; else goto <bb 3>; <bb 3>: # a_2 = PHI <0(2), 100(4)> # pi_4 = PHI <yi_8(2), pi_9(4)> pi.0_10 = (int *) pi_4; *pi.0_10 = 15; printf ("a=%d x=%d\n", a_2, 0); // <-- constant folded across the *pi store // because it was incorrectly proven to not // alias with x Test case by Gil Hur.