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