On Mon, Dec 22, 2025 at 12:02 PM Jason Merrill <[email protected]> wrote:
>
> On 12/21/25 2:02 PM, Yuao Ma wrote:
> > Hello world,
> >
> > This patch fixes an ICE encountered when using implicit constexpr. The
> > issue can be reproduced here:
> > https://compiler-explorer.com/z/39MsxKxTT. I have further reduced this
> > example to the test case included in the patch.
> >
> > I bisected the regression to commit r15-3631-g4ee692337c4ec1.
>
> Please also file a bug if there isn't one already.
>

Filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123261.

> > The root cause of the crash is that the function body is discarded to
> > void_cst when using implicit constexpr. We need to preserve the
> > function body to prevent this ICE during diagnostics.
> >
> > Regression tested on aarch64-linux. Ok for trunk?
> >
> > Thanks,
> > Yuao
>
> > +      if (!DECL_DECLARED_CONSTEXPR_P (fn) && !flag_implicit_constexpr
>
> How about using maybe_constexpr_fn?
>

Looks like it also works! Updated patch accordingly.

Thanks,
Yuao
From f628e481da632bb1236b9a0ea9d17e05fb3a444a Mon Sep 17 00:00:00 2001
From: Yuao Ma <[email protected]>
Date: Tue, 23 Dec 2025 00:40:54 +0800
Subject: [PATCH] c++: fix function body cloning when using implicit constexpr

When using implicit constexpr, we should not discard the function body, as it
can result in ICE during constant evaluation.

        PR c++/123261

gcc/cp/ChangeLog:

        * semantics.cc (expand_or_defer_fn_1): Use maybe_constexpr_fn.

gcc/testsuite/ChangeLog:

        * g++.dg/ext/fimplicit-constexpr2.C: New test.
---
 gcc/cp/semantics.cc                            |  2 +-
 .../g++.dg/ext/fimplicit-constexpr2.C          | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/fimplicit-constexpr2.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a2d655a60c1..e598632d85b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5578,7 +5578,7 @@ expand_or_defer_fn_1 (tree fn)
         the maybe-in-charge cdtor and regenerate the clones from it on
         demand, so we also need to keep the body.  Otherwise we don't
         need it anymore.  */
-      if (!DECL_DECLARED_CONSTEXPR_P (fn)
+      if (!maybe_constexpr_fn (fn)
          && !(module_maybe_has_cmi_p () && vague_linkage_p (fn)))
        DECL_SAVED_TREE (fn) = void_node;
       return false;
diff --git a/gcc/testsuite/g++.dg/ext/fimplicit-constexpr2.C 
b/gcc/testsuite/g++.dg/ext/fimplicit-constexpr2.C
new file mode 100644
index 00000000000..f72323ee831
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/fimplicit-constexpr2.C
@@ -0,0 +1,18 @@
+// { dg-additional-options -fimplicit-constexpr }
+// { dg-do compile { target c++23 } }
+
+class A
+{
+public:
+  A () { asm volatile (""); } // { dg-error {inline assembly is not a constant 
expression} }
+  ~A () {}
+};
+
+constexpr bool
+test ()
+{
+  A a; // { dg-error {'A::A\(\)' called in a constant expression} }
+  return true;
+}
+
+static_assert (test ()); // { dg-error {non-constant condition for static 
assertion} }
-- 
2.52.0

Reply via email to