On Wed, Jan 27, 2021 at 1:29 PM Alexandre Oliva <ol...@adacore.com> wrote:
>
> On Jan 26, 2021, Richard Biener <richard.guent...@gmail.com> wrote:
>
> > So while I think it's safe let's look at if we can improve tree-nested.c,
> > like I see (probably not the correct place):
>
> *nod*, it's just not the *only* place.
>
> > seeing how we adjust current_function_decl around the
> > recompute_tree_invariant_for_addr_expr call but not the
> > gsi_gimplify_val one (we already pass it a nesting_info,
> > not sure if wi->info is the same as the 'info' used above though),
> > so eventually we can fix it in one place?
>
> There are pieces of nested function lowering for which we set cfun and
> current_function_decl while walking each function, and there are other
> pieces that just don't bother, and we only set up current_function_decl
> temporarily for ADDR_EXPR handling.
>
> This patch adjusts both of the ADDR_EXPR handlers that override
> current_function_decl, so that the temporary overriding remains in
> effect during the re-gimplification.  That is enough to avoid the
> problem.  But I'm not very happy with this temporary overriding, it
> seems fishy.  I'd rather we set things up for the entire duration of the
> walking of each function.
>
> But that's only relevant because we rely on current_function_decl for
> address handling.  It's not clear to me that we should, as the other
> patch demonstrated.  With it, we could probably even do away with these
> overriders.

True, but I guess at least documentation of the predicates need to be
more precise.  I've also considered making the current_function_decl
accesses function parameters instead.  We do have
decl_address_ip_invariant_p on which decl_address_invariant_p
could build on by simply doing

 decl_address_ip_invariant_p (op) || auto_var_p (op)

(if there were not the strange STRING_CST handling in the _ip_ variant)

> But, for this stage, this is probably as conservative a change as we
> could possibly hope for.  I've regstrapped it on x86_64-linux-gnu, and
> also bootstrapped it with asan and ubsan.  Ok to install?

Yes, OK.

Thanks,
Richard.

>
> restore current_function_decl after re-gimplifying nested ADDR_EXPRs
>
> From: Alexandre Oliva <ol...@adacore.com>
>
> Ada makes extensive use of nested functions, which turn all automatic
> variables of the enclosing function that are used in nested ones into
> members of an artificial FRAME record type.
>
> The address of a local variable is usually passed to asan marking
> functions without using a temporary.  asan_expand_mark_ifn will reject
> an ADDR_EXPRs if it's split out from the call into an SSA_NAMEs.
>
> Taking the address of a member of FRAME within a nested function was
> not regarded as a gimple val: while introducing FRAME variables,
> current_function_decl pointed to the outermost function, even while
> processing a nested function, so decl_address_invariant_p, checking
> that the context of the variable is current_function_decl, returned
> false for such ADDR_EXPRs.
>
> decl_address_invariant_p, called when determining whether an
> expression is a legitimate gimple value, compares the context of
> automatic variables with current_function_decl.  Some of the
> tree-nested function processing doesn't set current_function_decl, but
> ADDR_EXPR-processing bits temporarily override it.  However, they
> restore it before re-gimplifying, which causes even ADDR_EXPRs
> referencing automatic variables in the FRAME struct of a nested
> function to not be regarded as address-invariant.
>
> This patch moves the restores of current_function_decl in the
> ADDR_EXPR-handling bits after the re-gimplification, so that the
> correct current_function_decl is used when testing for address
> invariance.
>
>
> for  gcc/ChangeLog
>
>         * tree-nested.c (convert_nonlocal_reference_op): Move
>         current_function_decl restore after re-gimplification.
>         (convert_local_reference_op): Likewise.
>
> for  gcc/testsuite/ChangeLog
>
>         * gcc.dg/asan/nested-1.c: New.
> ---
>  gcc/testsuite/gcc.dg/asan/nested-1.c |   24 ++++++++++++++++++++++++
>  gcc/tree-nested.c                    |    4 ++--
>  2 files changed, 26 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/asan/nested-1.c
>
> diff --git a/gcc/testsuite/gcc.dg/asan/nested-1.c 
> b/gcc/testsuite/gcc.dg/asan/nested-1.c
> new file mode 100644
> index 0000000000000..87e842098077c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/asan/nested-1.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize=address" } */
> +
> +int f(int i) {
> +  auto int h() {
> +    int r;
> +    int *p;
> +
> +    {
> +      int x[3];
> +
> +      auto int g() {
> +       return x[i];
> +      }
> +
> +      p = &r;
> +      *p = g();
> +    }
> +
> +    return *p;
> +  }
> +
> +  return h();
> +}
> diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
> index 1b52669b622aa..addd6eef9aba6 100644
> --- a/gcc/tree-nested.c
> +++ b/gcc/tree-nested.c
> @@ -1214,7 +1214,6 @@ convert_nonlocal_reference_op (tree *tp, int 
> *walk_subtrees, void *data)
>             save_context = current_function_decl;
>             current_function_decl = info->context;
>             recompute_tree_invariant_for_addr_expr (t);
> -           current_function_decl = save_context;
>
>             /* If the callback converted the address argument in a context
>                where we only accept variables (and min_invariant, presumably),
> @@ -1222,6 +1221,7 @@ convert_nonlocal_reference_op (tree *tp, int 
> *walk_subtrees, void *data)
>             if (save_val_only)
>               *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
>                                       t, &wi->gsi);
> +           current_function_decl = save_context;
>           }
>        }
>        break;
> @@ -1969,13 +1969,13 @@ convert_local_reference_op (tree *tp, int 
> *walk_subtrees, void *data)
>           save_context = current_function_decl;
>           current_function_decl = info->context;
>           recompute_tree_invariant_for_addr_expr (t);
> -         current_function_decl = save_context;
>
>           /* If we are in a context where we only accept values, then
>              compute the address into a temporary.  */
>           if (save_val_only)
>             *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
>                                     t, &wi->gsi);
> +         current_function_decl = save_context;
>         }
>        break;
>
>
>
> --
> Alexandre Oliva, happy hacker  https://FSFLA.org/blogs/lxo/
>    Free Software Activist         GNU Toolchain Engineer
>         Vim, Vi, Voltei pro Emacs -- GNUlius Caesar

Reply via email to