https://gcc.gnu.org/g:fa6544ef5f50a824cabeda4906453d4545fbf66f

commit r16-4228-gfa6544ef5f50a824cabeda4906453d4545fbf66f
Author: Nathaniel Shead <[email protected]>
Date:   Fri Sep 26 22:10:15 2025 +1000

    c++/modules: Avoid ICE when redefining a type reachable via import 
[PR122053]
    
    This shouldn't be an error (see PR c++/99000), but we can at least avoid
    the ICE by ensuring that we load any pending type definition before
    calling pushdecl, so that we error before committing to filling in the
    class definition.
    
    Something like this will probably still be helpful even for implementing
    textual deduplication as we now at least ensure check_module_override is
    called for this case.
    
            PR c++/122053
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (pushtag): Load any imported definition of type
            before calling pushdecl.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/pr122053_a.C: New test.
            * g++.dg/modules/pr122053_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/name-lookup.cc                     |  6 ++++++
 gcc/testsuite/g++.dg/modules/pr122053_a.C | 10 ++++++++++
 gcc/testsuite/g++.dg/modules/pr122053_b.C |  9 +++++++++
 3 files changed, 25 insertions(+)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 85c7fcc7a6e8..09d16db2ead8 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -8597,6 +8597,12 @@ pushtag (tree name, tree type, TAG_how how)
        }
       else
        {
+         /* If an import is going to provide a definition for this tag,
+            load it now so that we don't get confused later when processing
+            this tag's definition.  */
+         if (modules_p ())
+           lazy_load_pendings (decl);
+
          decl = do_pushdecl_with_scope
            (decl, b, /*hiding=*/(how == TAG_how::HIDDEN_FRIEND));
          if (decl == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/modules/pr122053_a.C 
b/gcc/testsuite/g++.dg/modules/pr122053_a.C
new file mode 100644
index 000000000000..2a8748c6be01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr122053_a.C
@@ -0,0 +1,10 @@
+// PR c++/122053
+// { dg-additional-options "-fmodules -Wno-global-module" }
+// { dg-module-cmi M }
+
+module;
+struct mytime {
+  long a, b;
+};
+export module M;
+export mytime foo();
diff --git a/gcc/testsuite/g++.dg/modules/pr122053_b.C 
b/gcc/testsuite/g++.dg/modules/pr122053_b.C
new file mode 100644
index 000000000000..a7084b74040a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr122053_b.C
@@ -0,0 +1,9 @@
+// PR c++/122053
+// { dg-additional-options "-fmodules" }
+// Test we don't ICE when redefining a type coming from an import.
+
+import M;
+struct mytime {  // { dg-bogus "conflicting" "PR99000" { xfail *-*-* } }
+  long a, b;
+};
+mytime m = foo();  // { dg-bogus "" "PR99000" { xfail *-*-* } }

Reply via email to