We were not correctly handling cross-module redeclarations of partial-specializations. They have their own TEMPLATE_DECL, which we need to locate. I had a FIXME there about this case. Guess it's fixed now.
PR 99480 gcc/cp/ * module.cc (depset::hash::make_dependency): Propagate flags for partial specialization. (module_may_redeclare): Handle partial specialization. gcc/testsuite/ * g++.dg/modules/pr99480_1.H: New. * g++.dg/modules/pr99480_b.H: New. -- Nathan Sidwell
diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc index ad3b7d53451..e4da5557f9e 100644 --- c/gcc/cp/module.cc +++ w/gcc/cp/module.cc @@ -12444,6 +12444,11 @@ depset::hash::make_dependency (tree decl, entity_kind ek) *slot = redirect; + if (DECL_LANG_SPECIFIC (decl)) + { + DECL_MODULE_IMPORT_P (partial) = DECL_MODULE_IMPORT_P (decl); + DECL_MODULE_PURVIEW_P (partial) = DECL_MODULE_PURVIEW_P (decl); + } depset *tmpl_dep = make_dependency (partial, EK_PARTIAL); gcc_checking_assert (tmpl_dep->get_entity_kind () == EK_PARTIAL); @@ -18429,13 +18434,20 @@ module_may_redeclare (tree decl) if (tree ti = node_template_info (decl, use_tpl)) { tree tmpl = TI_TEMPLATE (ti); - if (DECL_TEMPLATE_RESULT (tmpl) == decl) + if (use_tpl == 2) + { + /* A partial specialization. Find that specialization's + template_decl. */ + for (tree list = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); + list; list = TREE_CHAIN (list)) + if (DECL_TEMPLATE_RESULT (TREE_VALUE (list)) == decl) + { + decl = TREE_VALUE (list); + break; + } + } + else if (DECL_TEMPLATE_RESULT (tmpl) == decl) decl = tmpl; - // FIXME: What about partial specializations? We need to - // look at the specialization list in that case. Unless our - // caller's given us the right thing. An alternative would - // be to put both the template and the result into the - // entity hash, but that seems expensive? } unsigned index = import_entity_index (decl); them = import_entity_module (index); diff --git c/gcc/testsuite/g++.dg/modules/pr99480_a.H w/gcc/testsuite/g++.dg/modules/pr99480_a.H new file mode 100644 index 00000000000..8f48493c491 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99480_a.H @@ -0,0 +1,10 @@ +// PR 99480 ICE on instantiation definition +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +template<typename _Tp> +struct atomic; + +template<typename _Tp> +struct atomic<_Tp*>; + + diff --git c/gcc/testsuite/g++.dg/modules/pr99480_b.H w/gcc/testsuite/g++.dg/modules/pr99480_b.H new file mode 100644 index 00000000000..ea8800d67b0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99480_b.H @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +import "pr99480_a.H"; + +template<typename _Tp> +struct atomic<_Tp*> +{ +};