diff options
author | Nathan Sidwell <nathan@acm.org> | 2021-03-22 12:35:35 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2021-03-22 12:40:33 -0700 |
commit | 2bfd081f1bce3fb7f791591e741723dce4e884ed (patch) | |
tree | 532930ceb4c3ee75d3c0c1cf0433b87d86616f59 /gcc | |
parent | 02f2dc441b1954736cc61e3f97687cd23d5586c5 (diff) | |
download | gcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.zip gcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.tar.gz gcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/module.cc | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99480_a.H | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99480_b.H | 9 |
3 files changed, 37 insertions, 6 deletions
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<typename _Tp> +struct atomic; + +template<typename _Tp> +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<typename _Tp> +struct atomic<_Tp*> +{ +}; |