diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-03-05 20:36:36 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-03-05 20:36:36 -0500 |
commit | b0d11bb02a4a4c7d61e9b53411ccdc54610b1429 (patch) | |
tree | 3fa60882824d5d59a8597b9354ecaa8ea3f2cb48 /gcc | |
parent | 214dadf30a3bab0d02b8c6512a2d0475e2643dc7 (diff) | |
download | gcc-b0d11bb02a4a4c7d61e9b53411ccdc54610b1429.zip gcc-b0d11bb02a4a4c7d61e9b53411ccdc54610b1429.tar.gz gcc-b0d11bb02a4a4c7d61e9b53411ccdc54610b1429.tar.bz2 |
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 <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/module.cc | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/friend-7.h | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/friend-7_a.H | 3 | ||||
-rw-r--r-- | 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 67f132d..80b63a7 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 0000000..c0f0039 --- /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 0000000..e750e4c --- /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 0000000..eb5e45a --- /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; |