On 4/25/25 10:30 AM, Nathaniel Shead wrote:
Tested so far on x86_64-pc-linux-gnu (just modules.exp), OK for trunk/15
if full bootstrap+regtest succeeds?

OK.

A potentially safer approach that would slightly bloat out the size of
the built modules would be to always stream this variable rather than
having any conditions, but from what I can tell this change should be
sufficient; happy to go that way if you prefer though.

-- >8 --

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 <nathanielosh...@gmail.com>
---
  gcc/cp/module.cc                            | 4 ++--
  gcc/testsuite/g++.dg/modules/concept-11_a.H | 9 +++++++++
  gcc/testsuite/g++.dg/modules/concept-11_b.C | 9 +++++++++
  3 files changed, 20 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/concept-11_a.H
  create mode 100644 gcc/testsuite/g++.dg/modules/concept-11_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 5ff5c462e79..a2e0d6d2571 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 00000000000..45127682812
--- /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 00000000000..3f6676ff965
--- /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;
+}

Reply via email to