aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2025-04-26 00:10:34 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2025-04-27 22:55:16 +1000
commit1c5cf7cc82d3a2afa5d4fb90049456be408c2a7a (patch)
tree4c6ed1a0efd9238658fd7e1335ed753ec511e938 /gcc
parentf962f594e9006651379dafc9ef039be9654e6291 (diff)
downloadgcc-1c5cf7cc82d3a2afa5d4fb90049456be408c2a7a.zip
gcc-1c5cf7cc82d3a2afa5d4fb90049456be408c2a7a.tar.gz
gcc-1c5cf7cc82d3a2afa5d4fb90049456be408c2a7a.tar.bz2
c++/modules: Ensure DECL_FRIEND_CONTEXT is streamed [PR119939]
An instantiated friend function relies on DECL_FRIEND_CONTEXT being set to be able to recover the template arguments of the class that instantiated it, despite not being a template itself. This patch ensures that this data is streamed even when DECL_CLASS_SCOPE_P is not true. PR c++/119939 gcc/cp/ChangeLog: * module.cc (trees_out::lang_decl_vals): Also stream lang->u.fn.context when DECL_UNIQUE_FRIEND_P. (trees_in::lang_decl_vals): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/concept-11_a.H: New test. * g++.dg/modules/concept-11_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/module.cc4
-rw-r--r--gcc/testsuite/g++.dg/modules/concept-11_a.H9
-rw-r--r--gcc/testsuite/g++.dg/modules/concept-11_b.C9
3 files changed, 20 insertions, 2 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 5ff5c46..a2e0d6d 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -7386,7 +7386,7 @@ trees_out::lang_decl_vals (tree t)
WU (lang->u.fn.ovl_op_code);
}
- if (DECL_CLASS_SCOPE_P (t))
+ if (DECL_CLASS_SCOPE_P (t) || DECL_UNIQUE_FRIEND_P (t))
WT (lang->u.fn.context);
if (lang->u.fn.thunk_p)
@@ -7470,7 +7470,7 @@ trees_in::lang_decl_vals (tree t)
lang->u.fn.ovl_op_code = code;
}
- if (DECL_CLASS_SCOPE_P (t))
+ if (DECL_CLASS_SCOPE_P (t) || DECL_UNIQUE_FRIEND_P (t))
RT (lang->u.fn.context);
if (lang->u.fn.thunk_p)
diff --git a/gcc/testsuite/g++.dg/modules/concept-11_a.H b/gcc/testsuite/g++.dg/modules/concept-11_a.H
new file mode 100644
index 0000000..4512768
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/concept-11_a.H
@@ -0,0 +1,9 @@
+// PR c++/119939
+// { dg-additional-options "-fmodule-header -std=c++20" }
+// { dg-module-cmi {} }
+
+template <typename T> concept A = true;
+template <typename T> concept B = requires { T{}; };
+template <typename T> struct S {
+ friend bool operator==(const S&, const S&) requires B<T> = default;
+};
diff --git a/gcc/testsuite/g++.dg/modules/concept-11_b.C b/gcc/testsuite/g++.dg/modules/concept-11_b.C
new file mode 100644
index 0000000..3f6676f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/concept-11_b.C
@@ -0,0 +1,9 @@
+// PR c++/119939
+// { dg-additional-options "-fmodules -std=c++20" }
+
+import "concept-11_a.H";
+
+int main() {
+ S<int> s;
+ s == s;
+}