From: Patrick Palka Date: Wed, 6 Mar 2024 01:36:36 +0000 (-0500) Subject: c++/modules: befriending template from current class scope X-Git-Tag: basepoints/gcc-15~812 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0d11bb02a4a4c7d61e9b53411ccdc54610b1429;p=thirdparty%2Fgcc.git 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) : 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 --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 67f132d28d7a..80b63a70a62c 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 000000000000..c0f00394f3bb --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-7.h @@ -0,0 +1,5 @@ +template +struct A { + template struct B { }; + template 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 000000000000..e750e4c7d8d8 --- /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 000000000000..eb5e45a3f431 --- /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 a; +A::B b;