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
