Message ID | 20240226205223.2403105-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++/modules: befriending template from current class scope | expand |
On Mon, 26 Feb 2024, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk? Ping. > > -- >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 > >
On 2/26/24 15:52, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk? OK. > -- >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;
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;