https://gcc.gnu.org/g:9abe0b4f76265a062f1646a0bff1f58b70ae5695
commit r16-6954-g9abe0b4f76265a062f1646a0bff1f58b70ae5695 Author: Jakub Jelinek <[email protected]> Date: Wed Jan 21 14:30:03 2026 +0100 c++: Fix ICE with constant evaluation of a = {CLOBBER} with ptrmemfn [PR123677] The following testcase ICEs when we evaluate a = {CLOBBER} stmt. The code assumes that if type is an aggregate type and *valp is non-NULL, then it must be a CONSTRUCTOR. That is usually the case, but there is one exception, *valp can be a PTRMEM_CST if TYPE_PTRMEMFUNC_P (type) and in that case CONSTRUCTOR_ELTS (*valp) obviously ICEs or misbehaves. Now, while I could do something like if (*valp && (!TYPE_PTRMEMFUNC_P (type) || TREE_CODE (*valp) != PTRMEM_CST)) just making sure TREE_CODE (*valp) == CONSTRUCTOR seems much easier and more readable. 2026-01-21 Jakub Jelinek <[email protected]> PR c++/123677 * constexpr.cc (cxx_eval_store_expression): Only clear CONSTRUCTOR_ELTS (*valp) if *valp is CONSTRUCTOR. * g++.dg/cpp2a/pr123677.C: New test. Diff: --- gcc/cp/constexpr.cc | 2 +- gcc/testsuite/g++.dg/cpp2a/pr123677.C | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 0873226bc061..b850bd7ced26 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8197,7 +8197,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, { if (AGGREGATE_TYPE_P (type)) { - if (*valp) + if (*valp && TREE_CODE (*valp) == CONSTRUCTOR) CONSTRUCTOR_ELTS (*valp) = nullptr; else *valp = build_constructor (type, nullptr); diff --git a/gcc/testsuite/g++.dg/cpp2a/pr123677.C b/gcc/testsuite/g++.dg/cpp2a/pr123677.C new file mode 100644 index 000000000000..160f1901393c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr123677.C @@ -0,0 +1,7 @@ +// PR c++/123677 +// { dg-do compile { target c++20 } } + +struct B { void foo (); }; +typedef void (B::*A) (); +struct C { constexpr C (A d) { auto e = new A (d); e->~A (); } }; +C c { &B::foo };
