On 7/31/26 11:21 AM, Jakub Jelinek wrote:
On Thu, Jul 30, 2026 at 10:29:23AM -0400, Jason Merrill wrote:
OK, though we might rename metafns_called to something like state_dependent
and mention EH in its comment.  That can be a trunk-only followup.

Here it is, ok for trunk if it passes full bootstrap/regtest?

OK.
2026-07-31  Jakub Jelinek  <[email protected]>

        * constexpr.cc (class constexpr_global_ctx): Rename metafns_called
        to state_dependent, expand comment about constexpr EH.
        (constexpr_global_ctx::constexpr_global_ctx ()): Rename
        metafns_called to state_dependent.
        (cxx_eval_cxa_builtin_fn): Likewise.
        (cxx_eval_call_expression): Likewise.

--- gcc/cp/constexpr.cc.jj      2026-07-31 08:58:16.466783923 +0200
+++ gcc/cp/constexpr.cc 2026-07-31 14:54:12.546848510 +0200
@@ -1221,15 +1221,19 @@ public:
       class types, etc.  Thus, we need to arrange for calls which call
       at least some metafunctions to be non-cacheable, because their behavior
       might not be the same.  Until we figure out which exact metafunctions
-     need this and which don't, do it for all of them.  */
-  bool metafns_called;
+     need this and which don't, do it for all of them.
+     Also used for some cases in constexpr EH, e.g. __cxa_rethrow,
+     __builtin_uncaught_exceptions and __builtin_current_exception, which can
+     be also dependent on some state (pending uncaught or caught exceptions)
+     not tracked in the constexpr call caching.  */
+  bool state_dependent;
/* Constructor. */
    constexpr_global_ctx ()
      : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
        consteval_block (NULL_TREE), heap_dealloc_count (0),
        uncaught_exceptions (0), contract_statement (NULL_TREE),
-      contract_condition_non_const (false), metafns_called (false) {}
+      contract_condition_non_const (false), state_dependent (false) {}
bool is_outside_lifetime (tree t)
    {
@@ -2120,7 +2124,7 @@ cxx_eval_cxa_builtin_fn (const constexpr
        ++ctx->global->uncaught_exceptions;
        /* Don't cache calls which rethrow, they depend on the current
         exception which might be caught in the caller.  */
-      ctx->global->metafns_called = true;
+      ctx->global->state_dependent = true;
        *jump_target = arg;
        return void_node;
      case CXA_BAD_CAST:
@@ -2202,7 +2206,7 @@ cxx_eval_cxa_builtin_fn (const constexpr
        /* Don't cache calls which call __builtin_uncaught_exceptions (),
         they depend on the current uncaught exceptions which might
         be the state from their caller.  */
-      ctx->global->metafns_called = true;
+      ctx->global->state_dependent = true;
        return build_int_cst (integer_type_node,
                            ctx->global->uncaught_exceptions);
      case BUILTIN_CURRENT_EXCEPTION:
@@ -2257,7 +2261,7 @@ cxx_eval_cxa_builtin_fn (const constexpr
          /* Don't cache calls which call __builtin_current_exception (),
             they depend on the current exception which might be caught
             in the caller.  */
-         ctx->global->metafns_called = true;
+         ctx->global->state_dependent = true;
          return build_constructor_single (TREE_TYPE (decl), fld, arg);
        }
      case STD_RETHROW_EXCEPTION:
@@ -4069,7 +4073,7 @@ cxx_eval_call_expression (const constexp
          *non_constant_p = true;
          return t;
        }
-      ctx->global->metafns_called = true;
+      ctx->global->state_dependent = true;
        tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
                                     jump_target);
        if (*jump_target)
@@ -4538,7 +4542,7 @@ cxx_eval_call_expression (const constexp
          call_ctx.call = &new_call;
          unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
          unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
-         bool save_metafns_called = ctx->global->metafns_called;
+         bool save_state_dependent = ctx->global->state_dependent;
/* Make sure we fold std::is_constant_evaluated to true in an
             immediate function.  */
@@ -4570,7 +4574,7 @@ cxx_eval_call_expression (const constexp
                return NULL_TREE;
            }
- ctx->global->metafns_called = false;
+         ctx->global->state_dependent = false;
tree jmp_target = NULL_TREE;
          cxx_eval_constant_expression (&call_ctx, body,
@@ -4612,9 +4616,9 @@ cxx_eval_call_expression (const constexp
                }
            }
- if (ctx->global->metafns_called)
+         if (ctx->global->state_dependent)
            cacheable = false;
-         ctx->global->metafns_called |= save_metafns_called;
+         ctx->global->state_dependent |= save_state_dependent;
/* At this point, the object's constructor will have run, so
             the object is no longer under construction, and its possible


        Jakub


Reply via email to