From 1c5cf7cc82d3a2afa5d4fb90049456be408c2a7a Mon Sep 17 00:00:00 2001 From: Nathaniel Shead Date: Sat, 26 Apr 2025 00:10:34 +1000 Subject: [PATCH] c++/modules: Ensure DECL_FRIEND_CONTEXT is streamed [PR119939] An instantiated friend function relies on DECL_FRIEND_CONTEXT being set to be able to recover the template arguments of the class that instantiated it, despite not being a template itself. This patch ensures that this data is streamed even when DECL_CLASS_SCOPE_P is not true. PR c++/119939 gcc/cp/ChangeLog: * module.cc (trees_out::lang_decl_vals): Also stream lang->u.fn.context when DECL_UNIQUE_FRIEND_P. (trees_in::lang_decl_vals): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/concept-11_a.H: New test. * g++.dg/modules/concept-11_b.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/module.cc | 4 ++-- gcc/testsuite/g++.dg/modules/concept-11_a.H | 9 +++++++++ gcc/testsuite/g++.dg/modules/concept-11_b.C | 9 +++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/concept-11_a.H create mode 100644 gcc/testsuite/g++.dg/modules/concept-11_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 5ff5c462e79..a2e0d6d2571 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -7386,7 +7386,7 @@ trees_out::lang_decl_vals (tree t) WU (lang->u.fn.ovl_op_code); } - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_CLASS_SCOPE_P (t) || DECL_UNIQUE_FRIEND_P (t)) WT (lang->u.fn.context); if (lang->u.fn.thunk_p) @@ -7470,7 +7470,7 @@ trees_in::lang_decl_vals (tree t) lang->u.fn.ovl_op_code = code; } - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_CLASS_SCOPE_P (t) || DECL_UNIQUE_FRIEND_P (t)) RT (lang->u.fn.context); if (lang->u.fn.thunk_p) diff --git a/gcc/testsuite/g++.dg/modules/concept-11_a.H b/gcc/testsuite/g++.dg/modules/concept-11_a.H new file mode 100644 index 00000000000..45127682812 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/concept-11_a.H @@ -0,0 +1,9 @@ +// PR c++/119939 +// { dg-additional-options "-fmodule-header -std=c++20" } +// { dg-module-cmi {} } + +template concept A = true; +template concept B = requires { T{}; }; +template struct S { + friend bool operator==(const S&, const S&) requires B = default; +}; diff --git a/gcc/testsuite/g++.dg/modules/concept-11_b.C b/gcc/testsuite/g++.dg/modules/concept-11_b.C new file mode 100644 index 00000000000..3f6676ff965 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/concept-11_b.C @@ -0,0 +1,9 @@ +// PR c++/119939 +// { dg-additional-options "-fmodules -std=c++20" } + +import "concept-11_a.H"; + +int main() { + S s; + s == s; +} -- 2.47.2