Hello. During bootstrap, I came to following test-case:
struct A { int regno; }; struct { A base; } typedef *df_ref; int *a; void fn1 (int N) { for (int i = 0; i < N; i++) { df_ref b; a[(b)->base.regno]++; } } As we expand all usages of an LHS of a ASAN_POISON to all uses, we propagate that to a PHI node that originally contained ASAN_MARK (UNPOISON): <bb 4> [0.00%]: ASAN_MARK (UNPOISON, &b, 8); a.0_1 = a; b.1_2 = b; _3 = b.1_2->base.regno; _4 = (long unsigned int) _3; _5 = _4 * 4; _6 = a.0_1 + _5; _7 = *_6; _8 = _7 + 1; *_6 = _8; ASAN_MARK (POISON, &b, 8); i_17 = i_9 + 1; goto <bb 3>; [0.00%] Is transformed to: <bb 3> [0.00%]: # i_9 = PHI <0(2), i_17(4)> # b_18 = PHI <b_19(D)(2), b_20(4)> if (i_9 >= N_13(D)) goto <bb 5>; [0.00%] else goto <bb 4>; [0.00%] <bb 4> [0.00%]: a.0_1 = a; b.1_2 = b_18; _3 = b.1_2->base.regno; _4 = (long unsigned int) _3; _5 = _4 * 4; _6 = a.0_1 + _5; _7 = *_6; _8 = _7 + 1; *_6 = _8; b_20 = ASAN_POISON (); i_17 = i_9 + 1; goto <bb 3>; [0.00%] Motivation for propagation over PHI nodes was: cat use.c int main (int argc, char **argv) { int *ptr = 0; if (argc == 1) { int my_char; ptr = &my_char; } if (ptr) return *ptr; return 0; } I'm thinking whether the selected approach is fundamentally wrong, our we'll have to stop the PHI propagation and we still be able to catch some cases with -O2? Thanks, Martin