On Mon, Mar 02, 2026 at 03:38:42PM -0500, Jason Merrill wrote:
> On 3/2/26 9:29 AM, Nathaniel Shead wrote:
> > Bootstrapped and regtested (so far just modules.exp) on
> > x86_64-pc-linux-gnu, OK for trunk/15 if full regtest passes?
> > 
> > -- >8 --
> > 
> > When a TU synthesizes a definition of a defaulted member function we
> > mark the TU that did this as the originating module, and so export it
> > from there.  If this TU is imported into a module that already has a
> > declaration of this entity the declarations should be merged.
> > 
> > This patch fixes an issue where this merging was not occurring for
> > explicitly defaulted member functions, by checking DECL_DEFAULTED_FN
> > instead of just DECL_ARTIFICIAL.
> 
> This looks like it will also include user-provided defaulted functions
> (DECL_DEFAULTED_OUTSIDE_CLASS_P), which seems undesirable.

Right.  It doesn't actually seem to make a difference currently (we
never call 'set_defining_module' for such functions, and they're
non-inline so we never emit definitions when they're attached to a named
module) but it's probably clearer to avoid them.  Here's an updated
patch.

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?

-- >8 --

When a TU synthesizes a definition of a defaulted member function we
mark the TU that did this as the originating module, and so export it
from there.  If this TU is imported into a module that already has a
declaration of this entity the declarations should be merged.

This patch fixes an issue where this merging was not occurring for
explicitly defaulted member functions, by checking DECL_DEFAULTED_FN
instead of just DECL_ARTIFICIAL.

        PR c++/124311

gcc/cp/ChangeLog:

        * module.cc (trees_in::key_mergeable): Check DECL_DEFAULTED_FN
        instead of DECL_ARTIFICIAL.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/imp-member-5_a.C: New test.
        * g++.dg/modules/imp-member-5_b.C: New test.
        * g++.dg/modules/imp-member-5_c.C: New test.

Signed-off-by: Nathaniel Shead <[email protected]>
Reviewed-by: Jason Merrill <[email protected]>
---
 gcc/cp/module.cc                              | 11 ++++++-----
 gcc/testsuite/g++.dg/modules/imp-member-5_a.C |  9 +++++++++
 gcc/testsuite/g++.dg/modules/imp-member-5_b.C |  8 ++++++++
 gcc/testsuite/g++.dg/modules/imp-member-5_c.C |  5 +++++
 4 files changed, 28 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/imp-member-5_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/imp-member-5_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/imp-member-5_c.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ccbf124876d..42069111c9b 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12322,11 +12322,12 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree 
decl, tree inner,
          case TYPE_DECL:
            gcc_checking_assert (!is_imported_temploid_friend);
            if (is_attached && !(state->is_module () || state->is_partition ())
-               /* Implicit member functions can come from
-                  anywhere.  */
-               && !(DECL_ARTIFICIAL (decl)
-                    && TREE_CODE (decl) == FUNCTION_DECL
-                    && !DECL_THUNK_P (decl)))
+               /* Implicit or in-class defaulted member functions
+                  can come from anywhere.  */
+               && !(TREE_CODE (decl) == FUNCTION_DECL
+                    && !DECL_THUNK_P (decl)
+                    && DECL_DEFAULTED_FN (decl)
+                    && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)))
              kind = "unique";
            else
              {
diff --git a/gcc/testsuite/g++.dg/modules/imp-member-5_a.C 
b/gcc/testsuite/g++.dg/modules/imp-member-5_a.C
new file mode 100644
index 00000000000..6f9482cb679
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/imp-member-5_a.C
@@ -0,0 +1,9 @@
+// PR c++/124311
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi A }
+
+export module A;
+export struct S {
+  int x = 0;
+  S() = default;
+};
diff --git a/gcc/testsuite/g++.dg/modules/imp-member-5_b.C 
b/gcc/testsuite/g++.dg/modules/imp-member-5_b.C
new file mode 100644
index 00000000000..d55219a8eba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/imp-member-5_b.C
@@ -0,0 +1,8 @@
+// PR c++/124311
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi B }
+
+export module B;
+export import A;
+export struct M { S h; };
+M m;
diff --git a/gcc/testsuite/g++.dg/modules/imp-member-5_c.C 
b/gcc/testsuite/g++.dg/modules/imp-member-5_c.C
new file mode 100644
index 00000000000..39770acd362
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/imp-member-5_c.C
@@ -0,0 +1,5 @@
+// PR c++/124311
+// { dg-additional-options "-fmodules" }
+
+import B;
+M m2;
-- 
2.51.0

Reply via email to