https://gcc.gnu.org/g:b0d11bb02a4a4c7d61e9b53411ccdc54610b1429
commit r14-9327-gb0d11bb02a4a4c7d61e9b53411ccdc54610b1429 Author: Patrick Palka <ppa...@redhat.com> Date: Tue Mar 5 20:36:36 2024 -0500 c++/modules: befriending template from current class scope Here the TEMPLATE_DECL representing the template friend declaration naming B has class scope since the template B has class scope, but get_merge_kind assumes all DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P TEMPLATE_DECL have namespace scope and wrongly returns MK_named instead of MK_local_friend for the friend. gcc/cp/ChangeLog: * module.cc (trees_out::get_merge_kind) <case depset::EK_DECL>: Accomodate class-scope DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P TEMPLATE_DECL. Consolidate IDENTIFIER_ANON_P cases. gcc/testsuite/ChangeLog: * g++.dg/modules/friend-7.h: New test. * g++.dg/modules/friend-7_a.H: New test. * g++.dg/modules/friend-7_b.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com> Diff: --- gcc/cp/module.cc | 19 +++++++++---------- gcc/testsuite/g++.dg/modules/friend-7.h | 5 +++++ gcc/testsuite/g++.dg/modules/friend-7_a.H | 3 +++ gcc/testsuite/g++.dg/modules/friend-7_b.C | 6 ++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 67f132d28d7..80b63a70a62 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -10498,21 +10498,20 @@ trees_out::get_merge_kind (tree decl, depset *dep) } } - if (RECORD_OR_UNION_TYPE_P (ctx)) + if (TREE_CODE (decl) == TEMPLATE_DECL + && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)) { - if (IDENTIFIER_ANON_P (DECL_NAME (decl))) - mk = MK_field; + mk = MK_local_friend; break; } - if (TREE_CODE (decl) == TEMPLATE_DECL - && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)) - mk = MK_local_friend; - else if (IDENTIFIER_ANON_P (DECL_NAME (decl))) + if (IDENTIFIER_ANON_P (DECL_NAME (decl))) { - if (DECL_IMPLICIT_TYPEDEF_P (decl) - && UNSCOPED_ENUM_P (TREE_TYPE (decl)) - && TYPE_VALUES (TREE_TYPE (decl))) + if (RECORD_OR_UNION_TYPE_P (ctx)) + mk = MK_field; + else if (DECL_IMPLICIT_TYPEDEF_P (decl) + && UNSCOPED_ENUM_P (TREE_TYPE (decl)) + && TYPE_VALUES (TREE_TYPE (decl))) /* Keyed by first enum value, and underlying type. */ mk = MK_enum; else diff --git a/gcc/testsuite/g++.dg/modules/friend-7.h b/gcc/testsuite/g++.dg/modules/friend-7.h new file mode 100644 index 00000000000..c0f00394f3b --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-7.h @@ -0,0 +1,5 @@ +template<class T> +struct A { + template<class U> struct B { }; + template<class U> friend struct B; +}; diff --git a/gcc/testsuite/g++.dg/modules/friend-7_a.H b/gcc/testsuite/g++.dg/modules/friend-7_a.H new file mode 100644 index 00000000000..e750e4c7d8d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-7_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } +#include "friend-7.h" diff --git a/gcc/testsuite/g++.dg/modules/friend-7_b.C b/gcc/testsuite/g++.dg/modules/friend-7_b.C new file mode 100644 index 00000000000..eb5e45a3f43 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-7_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +#include "friend-7.h" +import "friend-7_a.H"; + +A<int> a; +A<int>::B<char> b;