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:#️⃣: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.
This commit is contained in:
Nathan Sidwell 2021-03-22 12:35:35 -07:00
parent 02f2dc441b
commit 2bfd081f1b
3 changed files with 37 additions and 6 deletions

View file

@ -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);

View file

@ -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*>;

View file

@ -0,0 +1,9 @@
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
import "pr99480_a.H";
template<typename _Tp>
struct atomic<_Tp*>
{
};