From: Nathaniel Shead Date: Mon, 1 Dec 2025 13:43:18 +0000 (+1100) Subject: c++/modules: Stream DECL_CHAIN for decl_specialization_friend_p functions X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4247fc98bd910ff8af8bae2aec0dfc256fdde585;p=thirdparty%2Fgcc.git c++/modules: Stream DECL_CHAIN for decl_specialization_friend_p functions r16-5298 attached the owning class for a friend template specialisation on its DECL_CHAIN. However we don't stream DECL_CHAIN in general to avoid walking into unrelated entities on the scope chain; this patch adds a special case for these functions to ensure we don't lose this information. Ideally this would occur in trees_{out,in}::core_vals, but we can't check decl_specialization_friend_p until after DECL_TEMPLATE_INFO has been streamed, hence the slightly unusual placement. gcc/cp/ChangeLog: * module.cc (trees_out::lang_decl_vals): Stream DECL_CHAIN for decl_specialization_friend_p functions. (trees_in::lang_decl_vals): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/friend-12_a.C: New test. * g++.dg/modules/friend-12_b.C: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 91e305c280b..042b029a036 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -7524,6 +7524,12 @@ trees_out::lang_decl_vals (tree t) WT (access); } + /* A friend template specialisation stashes its owning class on its + DECL_CHAIN; we need to reconstruct this, but it needs to happen + after we stream the template_info so readers can know this is such + an entity. */ + if (decl_specialization_friend_p (t)) + WT (t->common.chain); break; case lds_ns: /* lang_decl_ns. */ @@ -7593,6 +7599,8 @@ trees_in::lang_decl_vals (tree t) lds_min: RT (lang->u.min.template_info); RT (lang->u.min.access); + if (decl_specialization_friend_p (t)) + RT (t->common.chain); break; case lds_ns: /* lang_decl_ns. */ diff --git a/gcc/testsuite/g++.dg/modules/friend-12_a.C b/gcc/testsuite/g++.dg/modules/friend-12_a.C new file mode 100644 index 00000000000..827c74b8f58 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-12_a.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules -Wno-global-module" } +// { dg-module-cmi M:part } + +module; +template struct basic_streambuf; +template void __copy_streambufs_eof(basic_streambuf*); +template struct basic_streambuf { + friend void __copy_streambufs_eof<>(basic_streambuf*); +}; +export module M:part; +void foo(basic_streambuf&) {} diff --git a/gcc/testsuite/g++.dg/modules/friend-12_b.C b/gcc/testsuite/g++.dg/modules/friend-12_b.C new file mode 100644 index 00000000000..7eb7014660f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-12_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules -Wno-global-module" } +// { dg-module-cmi M } + +export module M; +export import :part;