https://gcc.gnu.org/g:fd7635c7d81d8183300934f91b885ecca52dda9b
commit r16-7095-gfd7635c7d81d8183300934f91b885ecca52dda9b Author: vspefs <[email protected]> Date: Mon Jan 26 20:56:52 2026 +0000 c++/modules: Handle reflection SPLICE_SCOPE tree node 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]> Diff: --- gcc/cp/module.cc | 16 ++++++++++++++++ gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C | 12 ++++++++++++ gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C | 16 ++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index e2097027dbd9..2d9b727d2b3d 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 000000000000..3cf638aadb59 --- /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 000000000000..55132f2d8b1d --- /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); +}
