On Wed, Jan 18, 2017 at 04:34:48PM +0100, Martin Liška wrote:
> 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]++;
> }
> }
Well, in this case it is UB too, just not actually out of bounds access,
but use of uninitialized variable.
Perhaps what we should do, in addition to turning ASAN_MARK (POISON, &b, ...)
into b = ASAN_POISON (); turn ASAN_MARK (UNPOISON, &b, ...) into
b = b_YYY(D);
The following seems to do the job:
--- gcc/tree-ssa.c.jj 2017-01-19 17:20:15.000000000 +0100
+++ gcc/tree-ssa.c 2017-01-19 17:29:58.015356370 +0100
@@ -1911,7 +1911,16 @@ execute_update_addresses_taken (void)
gsi_replace (&gsi, call, GSI_SAME_STMT);
}
else
- gsi_remove (&gsi, true);
+ {
+ /* In ASAN_MARK (UNPOISON, &b, ...) the variable
+ is uninitialized. Avoid dependencies on
+ previous out of scope value. */
+ tree clobber
+ = build_constructor (TREE_TYPE (var), NULL);
+ TREE_THIS_VOLATILE (clobber) = 1;
+ gimple *g = gimple_build_assign (var, clobber);
+ gsi_replace (&gsi, g, GSI_SAME_STMT);
+ }
continue;
}
}
Jakub