Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
Here A<S> is not instantiated in _a, so the exported a_s typedef is to an
incomplete type. It's instantiated in _b, but when marking things reachable
we get as far as the imported typedef and stop, so we don't write out the
instantiation. Then in _c we read in the definition of Outer with an
incomplete type for 'sub', and ICE when trying to initialize it in the
constructor.
Fixed by looking into the DECL_ORIGINAL_TYPE of an imported typedef when
gathering dependencies.
PR c++/125768
gcc/cp/ChangeLog:
* module.cc (trees_out::decl_node): When not streaming,
recurse into DECL_ORIGINAL_TYPE of an imported typedef.
gcc/testsuite/ChangeLog:
* g++.dg/modules/alias-3_a.C: New test.
* g++.dg/modules/alias-3_b.C: New test.
* g++.dg/modules/alias-3_c.C: New test.
---
gcc/cp/module.cc | 5 +++++
gcc/testsuite/g++.dg/modules/alias-3_a.C | 7 +++++++
gcc/testsuite/g++.dg/modules/alias-3_b.C | 9 +++++++++
gcc/testsuite/g++.dg/modules/alias-3_c.C | 5 +++++
4 files changed, 26 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/modules/alias-3_a.C
create mode 100644 gcc/testsuite/g++.dg/modules/alias-3_b.C
create mode 100644 gcc/testsuite/g++.dg/modules/alias-3_c.C
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index d81db520bab..17390356b09 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -9434,6 +9434,11 @@ trees_out::decl_node (tree decl, walk_kind ref)
case TYPE_DECL:
if (DECL_TINFO_P (decl))
goto tinfo;
+ /* c++/125768: For an imported typedef, also mark the original type
+ reachable in case it was instantiated here. */
+ if (!streaming_p () && DECL_ORIGINAL_TYPE (decl)
+ && (DECL_LANG_SPECIFIC (decl) && DECL_MODULE_IMPORT_P (decl)))
+ tree_node (DECL_ORIGINAL_TYPE (decl));
break;
}
diff --git a/gcc/testsuite/g++.dg/modules/alias-3_a.C
b/gcc/testsuite/g++.dg/modules/alias-3_a.C
new file mode 100644
index 00000000000..5292a47c5c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/alias-3_a.C
@@ -0,0 +1,7 @@
+// PR c++/125768
+// { dg-additional-options -fmodules }
+
+export module api;
+export struct S { };
+export template <class T> struct A { };
+export using a_s = A<S>;
diff --git a/gcc/testsuite/g++.dg/modules/alias-3_b.C
b/gcc/testsuite/g++.dg/modules/alias-3_b.C
new file mode 100644
index 00000000000..441b090490c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/alias-3_b.C
@@ -0,0 +1,9 @@
+// PR c++/125768
+// { dg-additional-options -fmodules }
+
+export module outer;
+import api;
+struct Outer {
+ a_s sub;
+ Outer();
+};
diff --git a/gcc/testsuite/g++.dg/modules/alias-3_c.C
b/gcc/testsuite/g++.dg/modules/alias-3_c.C
new file mode 100644
index 00000000000..708f2cdcfa2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/alias-3_c.C
@@ -0,0 +1,5 @@
+// PR c++/125768
+// { dg-additional-options -fmodules }
+
+module outer;
+Outer::Outer() {}
base-commit: 19bc99cb9c0f85da79bee41fabf40461b64d2cd1
--
2.54.0