Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?
-- >8 -- Here the TEMPLATE_DECL representing the template friend declaration for B has class scope since 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. gcc/cp/ChangeLog: * module.cc (trees_out::get_merge_kind) <case depset::EK_DECL>: Accomodate class-scope DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P TEMPLATE_DECL. Merge IDENTIFIER_ANON_P branches. 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. --- 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 | 5 +++++ 4 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/friend-7.h create mode 100644 gcc/testsuite/g++.dg/modules/friend-7_a.H create mode 100644 gcc/testsuite/g++.dg/modules/friend-7_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 106af7bdb3e..fa91c6ff9cb 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -10491,21 +10491,20 @@ trees_out::get_merge_kind (tree decl, depset *dep) break; } - 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..d90b685d89d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-7_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +#include "friend-7.h" +import "friend-7_a.H"; + +A<int> a; -- 2.44.0.rc1.15.g4fc51f00ef