On 6/30/23 23:28, Nathaniel Shead via Gcc-patches wrote:
This adds rudimentary lifetime tracking in C++ constexpr contexts,

Thanks!

I'm not seeing either a copyright assignment or DCO certification for you; please see https://gcc.gnu.org/contribute.html#legal for more information.

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index cca0435bafc..bc59b4aab67 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1188,7 +1190,12 @@ public:
      if (!already_in_map && modifiable)
        modifiable->add (t);
    }
-  void remove_value (tree t) { values.remove (t); }
+  void remove_value (tree t)
+  {
+    if (DECL_P (t))
+      outside_lifetime.add (t);
+    values.remove (t);

What if, instead of removing the variable from one hash table and adding it to another, we change the value to, say, void_node?

+         /* Also don't cache a call if we return a pointer to an expired
+            value.  */
+         if (cacheable && (cp_walk_tree_without_duplicates
+                           (&result, find_expired_values,
+                            &ctx->global->outside_lifetime)))
+           cacheable = false;

I think we need to reconsider cacheability in general; I think we only want to cache calls that are themselves valid constant expressions, in that the return value is a "permitted result of a constant expression" (https://eel.is/c++draft/expr.const#13). A pointer to an automatic variable is not, whether or not it is currently within its lifetime.

That is, only cacheable if reduced_constant_expression_p (result).

I'm experimenting with this now, you don't need to mess with it.

@@ -7085,7 +7138,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
      case PARM_DECL:
        if (lval && !TYPE_REF_P (TREE_TYPE (t)))
        /* glvalue use.  */;
-      else if (tree v = ctx->global->get_value (r))
+      else if (tree v = ctx->global->get_value (t))

I agree with this change, but it doesn't have any actual effect, right? I'll go ahead and apply it separately.

@@ -7328,17 +7386,28 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
        auto_vec<tree, 2> cleanups;
        vec<tree> *prev_cleanups = ctx->global->cleanups;
        ctx->global->cleanups = &cleanups;
-       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
+
+       auto_vec<tree, 10> save_exprs;

Now that we're going to track temporaries for each full-expression, I think we shouldn't also need to track them for loops and calls.

Jason

Reply via email to