[Bug middle-end/102285] New flag -ftrivial-auto-var-init=zero causes crash in pr82421.c

qinzhao at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Oct 1 20:23:35 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102285

--- Comment #18 from qinzhao at gcc dot gnu.org ---
(In reply to Richard Biener from comment #13)
> We could try sth like the following which should cover this testcase and
> also hopefully doesn't break anything else.
> 
> diff --git a/gcc/expr.c b/gcc/expr.c
> index e0bcbccd905..ab3b5b26c20 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -5322,7 +5322,7 @@ non_mem_decl_p (tree base)
>  /* Returns true if REF refers to an object that does not
>     reside in memory and has non-BLKmode.  */
>  
> -static inline bool
> +bool
>  mem_ref_refers_to_non_mem_p (tree ref)
>  {
>    tree base;
> diff --git a/gcc/expr.h b/gcc/expr.h
> index 94a85b40dca..85650e96834 100644
> --- a/gcc/expr.h
> +++ b/gcc/expr.h
> @@ -346,4 +346,6 @@ extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
>  /* Return an rtx for the size in bytes of the value of an expr.  */
>  extern rtx expr_size (tree);
>  
> +extern bool mem_ref_refers_to_non_mem_p (tree ref);
> +
>  #endif /* GCC_EXPR_H */
> diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
> index 8312d08aab2..c1d23dfd21e 100644
> --- a/gcc/internal-fn.c
> +++ b/gcc/internal-fn.c
> @@ -3015,8 +3015,10 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
>      reg_lhs = true;
>    else
>      {
> -      rtx tem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
> -      reg_lhs = !MEM_P (tem);
> +      tree lhs_base = lhs;
> +      while (handled_component_p (lhs_base))
> +       lhs_base = TREE_OPERAND (lhs_base, 0);
> +      reg_lhs = mem_refers_to_non_mem_p (lhs_base);
>      }
>  
>    if (!reg_lhs)

I tried the above patch, it even doesn't work for this testing case. 
After the patch, this call to .DEFERRED_INIT will be expanded through REG path,
however, the existing problem in the LHS IR broke the "expand_assignment" too. 
so, I still think that the root cause is the IR for LHS of the following call
to .DEFERRED_INIT is not correct:

MEM[(int[0:D.1993] *)&fb.3] = .DEFERRED_INIT (16, 2, 1);

the LHS is: MEM[(int[0:D.1993] *)&fb.3]

this is the MEM_REF, whose base address is a ADDR_EXPR of a VAR_DECL, however,
this VAR_DECL is not addressable, will be in REG. this is conflicting: how can
a variable that in a REG be address taken?


More information about the Gcc-bugs mailing list