[PATCH] c++: Fix ICE with constant evaluation of a = {CLOBBER} with ptrmemfn [PR123677]

Jakub Jelinek jakub@redhat.com
Wed Jan 21 09:24:15 GMT 2026


Hi!

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.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2026-01-21  Jakub Jelinek  <jakub@redhat.com>

	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.

--- gcc/cp/constexpr.cc.jj	2026-01-15 16:33:46.971098572 +0100
+++ gcc/cp/constexpr.cc	2026-01-20 17:33:25.928219375 +0100
@@ -8197,7 +8197,7 @@ cxx_eval_store_expression (const constex
     {
       if (AGGREGATE_TYPE_P (type))
 	{
-	  if (*valp)
+	  if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
 	    CONSTRUCTOR_ELTS (*valp) = nullptr;
 	  else
 	    *valp = build_constructor (type, nullptr);
--- gcc/testsuite/g++.dg/cpp2a/pr123677.C.jj	2026-01-20 17:37:35.056959819 +0100
+++ gcc/testsuite/g++.dg/cpp2a/pr123677.C	2026-01-20 17:37:13.330331372 +0100
@@ -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 };

	Jakub



More information about the Gcc-patches mailing list