From 2bfd081f1bce3fb7f791591e741723dce4e884ed Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 22 Mar 2021 12:35:35 -0700 Subject: [PATCH] c++: Cross-module partial specialiations [PR 99480] 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 c++/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_a.H: New. * g++.dg/modules/pr99480_b.H: New. --- gcc/cp/module.cc | 24 ++++++++++++++++++------ gcc/testsuite/g++.dg/modules/pr99480_a.H | 10 ++++++++++ gcc/testsuite/g++.dg/modules/pr99480_b.H | 9 +++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/pr99480_a.H create mode 100644 gcc/testsuite/g++.dg/modules/pr99480_b.H diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index ad3b7d5..e4da555 100644 --- a/gcc/cp/module.cc +++ b/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 a/gcc/testsuite/g++.dg/modules/pr99480_a.H b/gcc/testsuite/g++.dg/modules/pr99480_a.H new file mode 100644 index 0000000..8f48493 --- /dev/null +++ b/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 +struct atomic; + +template +struct atomic<_Tp*>; + + diff --git a/gcc/testsuite/g++.dg/modules/pr99480_b.H b/gcc/testsuite/g++.dg/modules/pr99480_b.H new file mode 100644 index 0000000..ea8800d --- /dev/null +++ b/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 +struct atomic<_Tp*> +{ +}; -- 2.7.4