diff mbox series

c++/modules: imported spec befriending class tmpl [PR114889]

Message ID 20240429135012.2862238-1-ppalka@redhat.com
State New
Headers show
Series c++/modules: imported spec befriending class tmpl [PR114889] | expand

Commit Message

Patrick Palka April 29, 2024, 1:50 p.m. UTC
Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
14 (I guess after 14.1 is released)?

-- >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

Comments

Jason Merrill April 29, 2024, 10:24 p.m. UTC | #1
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 mbox series

Patch

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();
+}