aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-04-29 21:27:59 -0400
committerPatrick Palka <ppalka@redhat.com>2024-04-29 21:27:59 -0400
commit22b20ac6c6aead2d3f36c413a77dd0b80adfec39 (patch)
tree871687057d22be59607e79ae7d195ce1cc9b6457
parent3900e944b0ac9db77380c5bb8635977dfd3b0691 (diff)
downloadgcc-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.cc2
-rw-r--r--gcc/testsuite/g++.dg/modules/friend-8_a.H23
-rw-r--r--gcc/testsuite/g++.dg/modules/friend-8_b.C9
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();
+}