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