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.

        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