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>
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)
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)
--- /dev/null
+// 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;
+};
--- /dev/null
+// PR c++/119939
+// { dg-additional-options "-fmodules -std=c++20" }
+
+import "concept-11_a.H";
+
+int main() {
+ S<int> s;
+ s == s;
+}