On 7/9/25 9:30 AM, Jakub Jelinek wrote:
On Tue, Jul 08, 2025 at 09:43:20PM -0400, Jason Merrill wrote:
@@ -3066,7 +3810,12 @@ cxx_eval_call_expression (const constexp
          return arg1;
        }
         else if (cxx_dynamic_cast_fn_p (fun))
-       return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p);
+       return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
+                                        jump_target);
+      else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
+       return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
+                                       non_constant_p, overflow_p,
+                                       jump_target);
         if (!ctx->quiet)
        {

If evaluating the arguments might throw, we can't give up at this point for
a non-constexpr function.

I don't understand this comment, at least in connection with the above
snippet, that just handles the magic calls.

Sorry I wasn't clear, the comment was about the existing code that follows the end of that hunk:

      if (!ctx->quiet)
        {
          if (!lambda_static_thunk_p (fun))
            error_at (loc, "call to non-%<constexpr%> function %qD", fun);
          explain_invalid_constexpr_fn (fun);
        }
      *non_constant_p = true;
      return t;

In C++26 we can't take this early exit before cxx_bind_parameters_in_call.

--- gcc/cp/decl.cc.jj   2025-05-31 00:43:13.835238535 +0200
+++ gcc/cp/decl.cc      2025-05-31 00:43:32.174996782 +0200
@@ -5070,6 +5070,18 @@ cxx_init_decl_processing (void)
                            BUILT_IN_FRONTEND, NULL, NULL_TREE);
     set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+  if (cxx_dialect >= cxx26)
+    {
+      tree void_ptrintftype
+       = build_function_type_list (void_type_node, ptr_type_node,
+                                   integer_type_node, NULL_TREE);
+      decl = add_builtin_function ("__builtin_eh_ptr_adjust_ref",

Instead of this, I wonder about hijacking the exception_ptr constructor and
destructor?  That doesn't need to be in this patch, just a thought. Do we
know if there's a clang/libc++ plan for constexpr exception_ptr yet?

Hana has some implementation on her branch, but I don't see progress in
trying to upstream that into LLVM.
The reason I've added a builtin is that unlike the __cxa_* functions or say
std::current_exception() etc. which are defined out of line (I think even in
libc++), most of the exception_ptr class cdtors and methods are defined
inline, for libstdc++ except for exception_ptr::_M_addref and
exception_ptr::_M_release which are out of line.  The names of those are
very libstdc++ specific though, libc++ uses something else.  Though the
operations (addref and release) are used in multiple places, e.g. in the
private ctor from void *, in copy ctor, and release from dtor, so figuring
out what exactly to hijack seems harder and less portable and future
standards can always add further methods to exception_ptr etc.
https://github.com/llvm/llvm-project/compare/main...hanickadot:llvm-project:hana/P3068-constexpr-exceptions#diff-58be87d6aa8658f15e1c1f3fa40acb71d078896d857cf98033b32f9fa294c320
is what I can see for exception_ptr, but whatever builtins they choose
in the end I guess depends on the upstreaming.  And they can choose to use
the same ones as GCC or libc++ can conditionalize that.

Aha, she has

      __constexpr_exception_refcount_inc(__ptr_);
      __constexpr_exception_refcount_dec(__ptr_);

so a similar approach, just with two builtins rather than one. So yeah, never mind for now, but we might try to coordinate builtin naming with them.

Jason

Reply via email to