Hi!
The following testcase is miscompiled, we throw exception only during
the first bar () call and not during the second and in that case reach
the inline asm.
The problem is that the TARGET_EXPR handling calls
ctx->global->put_value (new_ctx.object, new_ctx.ctor);
first for aggregate/vectors, then
if (is_complex)
/* In case no initialization actually happens, clear out any
void_node from a previous evaluation. */
ctx->global->put_value (slot, NULL_TREE);
and then recurses on TARGET_EXPR_INITIAL.
If that throws, we keep it as is and return. If (!is_complex), we
can in that case keep a value cached for the TARGET_EXPR_SLOT. For
*non_constant_p I think that is a non-issue, but for *jump_target
it can still be a constant expression.
The following patch fixes it by calling put_value in that case for
the !is_complex case.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or should it be called ragardless of !is_complex?
2026-03-04 Jakub Jelinek <[email protected]>
PR c++/124145
* constexpr.cc (cxx_eval_constant_expression) <case TARGET_EXPR>: If
*jump_target && !is_complex, call put_value with NULL_TREE value on
slot. Use TARGET_EXPR_INITIAL instead of TREE_OPERAND.
* g++.dg/cpp26/constexpr-eh18.C: New test.
--- gcc/cp/constexpr.cc.jj 2026-03-02 07:43:12.342788130 +0100
+++ gcc/cp/constexpr.cc 2026-03-03 13:41:31.435442193 +0100
@@ -9486,13 +9486,17 @@ cxx_eval_constant_expression (const cons
/* Pass vc_prvalue because this indicates
initialization of a temporary. */
- r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_prvalue,
- non_constant_p, overflow_p,
- jump_target);
+ r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
+ vc_prvalue, non_constant_p,
+ overflow_p, jump_target);
if (*non_constant_p)
break;
if (*jump_target)
- return NULL_TREE;
+ {
+ if (!is_complex)
+ ctx->global->put_value (slot, NULL_TREE);
+ return NULL_TREE;
+ }
if (!is_complex)
{
r = unshare_constructor (r);
--- gcc/testsuite/g++.dg/cpp26/constexpr-eh18.C.jj 2026-03-03
13:44:19.501639167 +0100
+++ gcc/testsuite/g++.dg/cpp26/constexpr-eh18.C 2026-03-03 13:43:51.868100042
+0100
@@ -0,0 +1,42 @@
+// PR c++/124145
+// { dg-do compile { target c++26 } }
+
+struct S {};
+
+constexpr S
+foo (S x)
+{
+ throw 123;
+ return x;
+}
+
+constexpr void
+bar ()
+{
+ foo (S {});
+}
+
+constexpr bool
+baz ()
+{
+ try
+ {
+ bar ();
+ asm ("");
+ }
+ catch (int)
+ {
+ }
+
+ try
+ {
+ bar ();
+ asm ("");
+ }
+ catch (int)
+ {
+ }
+ return true;
+}
+
+static_assert (baz ());
Jakub