https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114630
--- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> --- The following seems to minimally fix it: diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c35e70b8cb8..57ccaec5ebd 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -6798,7 +6798,7 @@ trees_in::core_vals (tree t) body) anyway. */ decl = maybe_duplicate (decl); - if (!DECL_P (decl) || DECL_CHAIN (decl)) + if (!DECL_P (decl) || (*chain && *chain != decl)) { set_overrun (); break; In 114630_c.C end up streaming the definition of _M_do_parse<int>() twice, once from modB and once from the transitive import of modA (which seems wasteful). The second time around the chain of local types _M_do_parse<int>::A/B get streamed as simple back references and therefore on stream-in they'll already have DECL_CHAIN properly set, so we shouldn't give up just because DECL_CHAIN is already set. Rather, only give up if DECL_CHAIN of the previous decl isn't what we expect it to be, i.e. either empty or what we want to set it to. This raises the question, why do we stream the definition of _M_do_parse<int>() from the GMF of modA even though the same definition is already reachable (and has been deduplicated) from the import of modB? Seems like this is something we could/should avoid.