]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Ensure DECL_FRIEND_CONTEXT is streamed [PR119939]
authorNathaniel Shead <nathanieloshead@gmail.com>
Fri, 25 Apr 2025 14:10:34 +0000 (00:10 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Sun, 27 Apr 2025 12:55:16 +0000 (22:55 +1000)
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>
gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/concept-11_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/concept-11_b.C [new file with mode: 0644]

index 5ff5c462e79cf84e15512731dc4938c7604ec53a..a2e0d6d257181fd85f2545e64a0f50119caa43e4 100644 (file)
@@ -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 (file)
index 0000000..4512768
--- /dev/null
@@ -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 (file)
index 0000000..3f6676f
--- /dev/null
@@ -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;
+}