On 1/28/26 3:42 AM, Patrick Palka wrote:
On Mon, 26 Jan 2026, vspefs wrote:

Previous patches contains errors. A new patch is attached.

I am so bad at git and I hope I get it right this time T_T

Subject: [PATCH] Handles `SPLICE_SCOPE` tree

This patch adds support for serializing and deserializing SPLICE_SCOPE trees in
C++20 modules implementation. SPLICE_SCOPE is introduced by C++26 reflection,
notably used for dependent splice types, thus needing to be exported/imported
as part of the module interface. Not handling SPLICE_SCOPE leads to ICE.

This patch also includes 2 simple test cases: one for exporting splice scope
types and another for importing them.

gcc/cp/

        * module.cc (trees_out::type_node): Add case for SPLICE_SCOPE.
        * module.cc (trees_in::tree_node): Add case for SPLICE_SCOPE.

gcc/testsuite/

        * g++.dg/modules/splice-scope-tree_a.C: New test.
        * g++.dg/modules/splice-scope-tree_b.C: New test.

Signed-off-by: vspefs <[email protected]>

Thanks for the patch! The code changes look good to me. However, I
believe we can't accept DCO sign-offs for pseudonyms :/ (see
https://gcc.gnu.org/dco.html)

Jason, do you reckon this change is small enough that we can accept it
without a DCO sign-off?

I think so, yes. I'm pushing this modification that adjusts the ChangeLog entry to make git gcc-verify happy, and replaces the sign-off with Reviewed-by.

From fd7635c7d81d8183300934f91b885ecca52dda9b Mon Sep 17 00:00:00 2001
From: vspefs <[email protected]>
Date: Mon, 26 Jan 2026 20:56:52 +0000
Subject: [PATCH] c++/modules: Handle reflection SPLICE_SCOPE tree node
To: [email protected]

This patch adds support for serializing and deserializing SPLICE_SCOPE trees
in C++20 modules implementation. SPLICE_SCOPE is introduced by C++26
reflection, notably used for dependent splice types, thus needing to be
exported/imported as part of the module interface. Not handling SPLICE_SCOPE
leads to ICE.

This patch also includes 2 simple test cases: one for exporting splice scope
types and another for importing them.

gcc/cp/

	* module.cc (trees_out::type_node): Add case for SPLICE_SCOPE.
	(trees_in::tree_node): Add case for SPLICE_SCOPE.

gcc/testsuite/

	* g++.dg/modules/splice-scope-tree_a.C: New test.
	* g++.dg/modules/splice-scope-tree_b.C: New test.

Reviewed-by: Patrick Palka  <[email protected]>
Reviewed-by: Jason Merrill <[email protected]>
---
 gcc/cp/module.cc                                 | 16 ++++++++++++++++
 .../g++.dg/modules/splice-scope-tree_a.C         | 12 ++++++++++++
 .../g++.dg/modules/splice-scope-tree_b.C         | 16 ++++++++++++++++
 3 files changed, 44 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index e2097027dbd..2d9b727d2b3 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -9847,6 +9847,12 @@ trees_out::type_node (tree type)
     case META_TYPE:
       /* No additional data.  */
       break;
+
+    case SPLICE_SCOPE:
+      if (streaming_p ())
+	u (SPLICE_SCOPE_TYPE_P (type));
+      tree_node (SPLICE_SCOPE_EXPR (type));
+      break;
     }
 
   tree_node (TYPE_ATTRIBUTES (type));
@@ -10697,6 +10703,16 @@ trees_in::tree_node (bool is_use)
 	    if (!get_overrun ())
 	      res = meta_info_type_node;
 	    break;
+
+	  case SPLICE_SCOPE:
+	    {
+	      bool type = u ();
+	      tree expr = tree_node ();
+
+	      if (!get_overrun ())
+		res = make_splice_scope (expr, type);
+	    }
+	    break;
 	  }
 
 	/* In the exporting TU, a derived type with attributes was built by
diff --git a/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C b/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
new file mode 100644
index 00000000000..3cf638aadb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fmodules -freflection" }
+
+export module exporting_splice_scope;
+// { dg-module-cmi exporting_splice_scope }
+
+export template <typename T>
+using dependent_splice_type = typename [: ^^T :];
+
+export template <bool Cond, typename T, typename U>
+using somehow_more_complicated_dependent_splice_type =
+    typename [: Cond ? ^^T : ^^U :];
diff --git a/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C b/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C
new file mode 100644
index 00000000000..55132f2d8b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fmodules -freflection" }
+
+import exporting_splice_scope;
+
+#include <meta>
+
+int
+main ()
+{
+  static_assert (std::meta::dealias (^^dependent_splice_type<int>) == ^^int);
+  static_assert (std::meta::dealias (
+      ^^somehow_more_complicated_dependent_splice_type<true, int, double>) == ^^int);
+  static_assert (std::meta::dealias (
+      ^^somehow_more_complicated_dependent_splice_type<false, int, double>) == ^^double);
+}
-- 
2.52.0

Reply via email to