https://gcc.gnu.org/g:63461fcfcf52092525ed2aad14181c179d68899a
commit r17-1790-g63461fcfcf52092525ed2aad14181c179d68899a Author: Jason Merrill <[email protected]> Date: Tue Jun 23 12:53:02 2026 -0400 c++/modules: imported incomplete typedef [PR125768] 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. Diff: --- 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(+) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index d81db520bab8..17390356b09c 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 000000000000..5292a47c5c28 --- /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 000000000000..441b090490c8 --- /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 000000000000..708f2cdcfa23 --- /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() {}
