On Mon, 21 Apr 2025, Jason Merrill wrote:

> Tested x86_64-pc-linux-gnu, OK for trunk?
> 
> -- 8< --
> 
> While working on PR119162 it occurred to me that it would be simpler to
> detect the problem of a value referring to a heap allocation if we stopped
> setting TREE_STATIC on them so they naturally are not considered to have a
> constant address.  With that change we no longer need to specifically avoid
> caching a value that refers to a deleted pointer.
> 
> But with this change maybe_nonzero_address is not sure whether the variable
> could have address zero.  I don't understand why it returns 1 only for
> variables in the current function, rather than all non-symtab decls; an auto
> variable from some other function also won't have address zero.  Maybe this
> made more sense when it was in tree_single_nonzero_warnv_p before r7-5868?
> 
> But assuming there is some reason for the current behavior, this patch only
> changes the handling of non-symtab decls when folding_cxx_constexpr.

FWIW the maybe_nonzero_address change seems to fix PR85944, yay!  Except for
the PR115207 dup, which we still reject with

115207.C:11:18: error: ‘(((const value*)(&<anonymous>)) != ((const value*)(& 
test.array<4>::_items)))’ is not a constant expression
   11 |         if (this != &other) {
      |             ~~~~~^~~~~~~~~

Could this mean another spot in the middle-end needs relaxing in order to
handle address comparisons of context-less local vars?

> 
>       PR c++/119162
> 
> gcc/cp/ChangeLog:
> 
>       * constexpr.cc (find_deleted_heap_var): Remove.
>       (cxx_eval_call_expression): Don't call it.  Don't set TREE_STATIC on
>       heap vars.
>       (cxx_eval_outermost_constant_expr): Don't mess with varpool.
> 
> gcc/ChangeLog:
> 
>       * fold-const.cc (maybe_nonzero_address): Return 1 for non-symtab
>       vars if folding_cxx_constexpr.
> ---
>  gcc/cp/constexpr.cc | 29 -----------------------------
>  gcc/fold-const.cc   | 25 ++++++++++++++++---------
>  2 files changed, 16 insertions(+), 38 deletions(-)
> 
> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> index 8a11e6265f2..5b7b70f7e65 100644
> --- a/gcc/cp/constexpr.cc
> +++ b/gcc/cp/constexpr.cc
> @@ -1550,7 +1550,6 @@ static tree cxx_eval_bare_aggregate (const 
> constexpr_ctx *, tree,
>  static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, 
> tree,
>                                  bool * = NULL);
>  static tree find_heap_var_refs (tree *, int *, void *);
> -static tree find_deleted_heap_var (tree *, int *, void *);
>  
>  /* Attempt to evaluate T which represents a call to a builtin function.
>     We assume here that all builtin functions evaluate to scalar types
> @@ -2975,14 +2974,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, 
> tree t,
>                                    : heap_uninit_identifier,
>                                    type);
>             DECL_ARTIFICIAL (var) = 1;
> -           TREE_STATIC (var) = 1;
> -           // Temporarily register the artificial var in varpool,
> -           // so that comparisons of its address against NULL are folded
> -           // through nonzero_address even with
> -           // -fno-delete-null-pointer-checks or that comparison of
> -           // addresses of different heap artificial vars is folded too.
> -           // See PR98988 and PR99031.
> -           varpool_node::finalize_decl (var);
>             ctx->global->heap_vars.safe_push (var);
>             ctx->global->put_value (var, NULL_TREE);
>             return fold_convert (ptr_type_node, build_address (var));
> @@ -3454,11 +3445,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, 
> tree t,
>                     cacheable = false;
>                     break;
>                   }
> -           /* And don't cache a ref to a deleted heap variable (119162).  */
> -           if (cacheable
> -               && (cp_walk_tree_without_duplicates
> -                   (&result, find_deleted_heap_var, NULL)))
> -             cacheable = false;
>           }
>  
>           /* Rewrite all occurrences of the function's RESULT_DECL with the
> @@ -9025,20 +9011,6 @@ find_heap_var_refs (tree *tp, int *walk_subtrees, void 
> */*data*/)
>    return NULL_TREE;
>  }
>  
> -/* Look for deleted heap variables in the expression *TP.  */
> -
> -static tree
> -find_deleted_heap_var (tree *tp, int *walk_subtrees, void */*data*/)
> -{
> -  if (VAR_P (*tp)
> -      && DECL_NAME (*tp) == heap_deleted_identifier)
> -    return *tp;
> -
> -  if (TYPE_P (*tp))
> -    *walk_subtrees = 0;
> -  return NULL_TREE;
> -}
> -
>  /* Find immediate function decls in *TP if any.  */
>  
>  static tree
> @@ -9275,7 +9247,6 @@ cxx_eval_outermost_constant_expr (tree t, bool 
> allow_non_constant,
>             r = t;
>             non_constant_p = true;
>           }
> -       varpool_node::get (heap_var)->remove ();
>       }
>      }
>  
> diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
> index c9471ea44b0..35fcf5087fb 100644
> --- a/gcc/fold-const.cc
> +++ b/gcc/fold-const.cc
> @@ -9917,22 +9917,29 @@ pointer_may_wrap_p (tree base, tree offset, 
> poly_int64 bitpos)
>  static int
>  maybe_nonzero_address (tree decl)
>  {
> +  if (!DECL_P (decl))
> +    return -1;
> +
>    /* Normally, don't do anything for variables and functions before symtab is
>       built; it is quite possible that DECL will be declared weak later.
>       But if folding_initializer, we need a constant answer now, so create
>       the symtab entry and prevent later weak declaration.  */
> -  if (DECL_P (decl) && decl_in_symtab_p (decl))
> -    if (struct symtab_node *symbol
> -     = (folding_initializer
> -        ? symtab_node::get_create (decl)
> -        : symtab_node::get (decl)))
> -      return symbol->nonzero_address ();
> +  if (decl_in_symtab_p (decl))
> +    {
> +      if (struct symtab_node *symbol
> +       = (folding_initializer
> +          ? symtab_node::get_create (decl)
> +          : symtab_node::get (decl)))
> +     return symbol->nonzero_address ();
> +    }
> +  else if (folding_cxx_constexpr)
> +    /* Anything that doesn't go in the symtab has non-zero address.  */
> +    return 1;
>  
>    /* Function local objects are never NULL.  */
> -  if (DECL_P (decl)
> -      && (DECL_CONTEXT (decl)
> +  if (DECL_CONTEXT (decl)
>        && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL
> -      && auto_var_in_fn_p (decl, DECL_CONTEXT (decl))))
> +      && auto_var_in_fn_p (decl, DECL_CONTEXT (decl)))
>      return 1;
>  
>    return -1;
> 
> base-commit: 9ac98b5742ebce41d7da9fda10852a0bc958f1cb
> -- 
> 2.49.0
> 
> 

Reply via email to