Message ID | 20240429135012.2862238-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++/modules: imported spec befriending class tmpl [PR114889] | expand |
On 4/29/24 06:50, Patrick Palka wrote: > Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps > 14 (I guess after 14.1 is released)? OK for both. > -- >8 -- > > We need to look through TEMPLATE_DECL like make_friend_class does when > adding to CLASSTYPE_BEFRIENDING_CLASSES. > > Otherwise in the below testcase we won't add _Hashtable<int, int> to > CLASSTYPE_BEFRIENDING_CLASSES of _Map_base when installing the definition > of the former which leads to access control issues. > > PR c++/114889 > > gcc/cp/ChangeLog: > > * module.cc (trees_in::read_class_def): Look through > TEMPLATE_DECL when adding to CLASSTYPE_BEFRIENDING_CLASSES. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/friend-8_a.H: New test. > * g++.dg/modules/friend-8_b.C: New test. > --- > gcc/cp/module.cc | 2 ++ > gcc/testsuite/g++.dg/modules/friend-8_a.H | 23 +++++++++++++++++++++++ > gcc/testsuite/g++.dg/modules/friend-8_b.C | 9 +++++++++ > 3 files changed, 34 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/modules/friend-8_a.H > create mode 100644 gcc/testsuite/g++.dg/modules/friend-8_b.C > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index 7e654305f0a..3b2ba40c92b 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -12518,6 +12518,8 @@ trees_in::read_class_def (tree defn, tree maybe_template) > for (; friend_classes; friend_classes = TREE_CHAIN (friend_classes)) > { > tree f = TREE_VALUE (friend_classes); > + if (TREE_CODE (f) == TEMPLATE_DECL) > + f = TREE_TYPE (f); > > if (CLASS_TYPE_P (f)) > { > diff --git a/gcc/testsuite/g++.dg/modules/friend-8_a.H b/gcc/testsuite/g++.dg/modules/friend-8_a.H > new file mode 100644 > index 00000000000..b07ea25adfb > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/friend-8_a.H > @@ -0,0 +1,23 @@ > +// PR c++/114889 > +// { dg-additional-options "-fmodule-header" } > +// { dg-module-cmi {} } > + > +template<class, class> > +struct _Hashtable; > + > +template<class _Key, class _Val> > +struct _Map_base { > + void f() { > + _Hashtable<_Key, _Val> __h; > + __h._M_hash_code(0); > + } > +}; > + > +template<class _Key, class _Value> > +struct _Hashtable { > + template<class, class> friend struct _Map_base; > +protected: > + void _M_hash_code(int); > +}; > + > +inline _Hashtable<int, int> m; > diff --git a/gcc/testsuite/g++.dg/modules/friend-8_b.C b/gcc/testsuite/g++.dg/modules/friend-8_b.C > new file mode 100644 > index 00000000000..b04280bc91a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/friend-8_b.C > @@ -0,0 +1,9 @@ > +// PR c++/114889 > +// { dg-additional-options "-fmodules-ts" } > + > +import "friend-8_a.H"; > + > +int main() { > + _Map_base<int, int> m; > + m.f(); > +}
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 7e654305f0a..3b2ba40c92b 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -12518,6 +12518,8 @@ trees_in::read_class_def (tree defn, tree maybe_template) for (; friend_classes; friend_classes = TREE_CHAIN (friend_classes)) { tree f = TREE_VALUE (friend_classes); + if (TREE_CODE (f) == TEMPLATE_DECL) + f = TREE_TYPE (f); if (CLASS_TYPE_P (f)) { diff --git a/gcc/testsuite/g++.dg/modules/friend-8_a.H b/gcc/testsuite/g++.dg/modules/friend-8_a.H new file mode 100644 index 00000000000..b07ea25adfb --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-8_a.H @@ -0,0 +1,23 @@ +// PR c++/114889 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template<class, class> +struct _Hashtable; + +template<class _Key, class _Val> +struct _Map_base { + void f() { + _Hashtable<_Key, _Val> __h; + __h._M_hash_code(0); + } +}; + +template<class _Key, class _Value> +struct _Hashtable { + template<class, class> friend struct _Map_base; +protected: + void _M_hash_code(int); +}; + +inline _Hashtable<int, int> m; diff --git a/gcc/testsuite/g++.dg/modules/friend-8_b.C b/gcc/testsuite/g++.dg/modules/friend-8_b.C new file mode 100644 index 00000000000..b04280bc91a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/friend-8_b.C @@ -0,0 +1,9 @@ +// PR c++/114889 +// { dg-additional-options "-fmodules-ts" } + +import "friend-8_a.H"; + +int main() { + _Map_base<int, int> m; + m.f(); +}