diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-04-29 21:27:59 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-04-29 21:27:59 -0400 |
commit | 22b20ac6c6aead2d3f36c413a77dd0b80adfec39 (patch) | |
tree | 871687057d22be59607e79ae7d195ce1cc9b6457 | |
parent | 3900e944b0ac9db77380c5bb8635977dfd3b0691 (diff) | |
download | gcc-22b20ac6c6aead2d3f36c413a77dd0b80adfec39.zip gcc-22b20ac6c6aead2d3f36c413a77dd0b80adfec39.tar.gz gcc-22b20ac6c6aead2d3f36c413a77dd0b80adfec39.tar.bz2 |
c++/modules: imported spec befriending class tmpl [PR114889]
When adding to CLASSTYPE_BEFRIENDING_CLASSES as part of installing an
imported class definition, we need to look through TEMPLATE_DECL like
make_friend_class does.
Otherwise in the below testcase we won't add _Hashtable<int, int> to
CLASSTYPE_BEFRIENDING_CLASSES of _Map_base, which leads to a bogus
access check failure for _M_hash_code.
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.
Reviewed-by: Jason Merrill <jason@redhat.com>
-rw-r--r-- | gcc/cp/module.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/friend-8_a.H | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/friend-8_b.C | 9 |
3 files changed, 34 insertions, 0 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c35e70b..3bf863e 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -12498,6 +12498,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 0000000..b07ea25 --- /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 0000000..b04280b --- /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(); +} |