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

Reply via email to