c++: Duplicate namespace bindings [PR 99245]

Header units can declare the same entity, and this can lead to one of
them containing a (non-using) binding to an import.  If one gets the
cluster ordering just right, an assert will trigger.  Relax that assert.

	PR c++/99245
	gcc/cp/
	* module.cc (module_state::write_cluster): Relax binding assert.
	gcc/testsuite/
	* g++.dg/modules/pr99245_a.H: New.
	* g++.dg/modules/pr99245_b.H: New.
This commit is contained in:
Nathan Sidwell 2021-03-05 12:49:34 -08:00
parent b1bee29167
commit 9e64dd6b3f
3 changed files with 33 additions and 14 deletions

View file

@ -14496,20 +14496,25 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
gcc_unreachable ();
case depset::EK_BINDING:
dump (dumper::CLUSTER)
&& dump ("[%u]=%s %P", ix, b->entity_kind_name (),
b->get_entity (), b->get_name ());
for (unsigned jx = b->deps.length (); jx--;)
{
depset *dep = b->deps[jx];
if (jx)
gcc_checking_assert (dep->get_entity_kind () == depset::EK_USING
|| TREE_VISITED (dep->get_entity ()));
else
gcc_checking_assert (dep->get_entity_kind ()
== depset::EK_NAMESPACE
&& dep->get_entity () == b->get_entity ());
}
{
dump (dumper::CLUSTER)
&& dump ("[%u]=%s %P", ix, b->entity_kind_name (),
b->get_entity (), b->get_name ());
depset *ns_dep = b->deps[0];
gcc_checking_assert (ns_dep->get_entity_kind ()
== depset::EK_NAMESPACE
&& ns_dep->get_entity () == b->get_entity ());
for (unsigned jx = b->deps.length (); --jx;)
{
depset *dep = b->deps[jx];
// We could be declaring something that is also a
// (merged) import
gcc_checking_assert (dep->is_import ()
|| TREE_VISITED (dep->get_entity ())
|| (dep->get_entity_kind ()
== depset::EK_USING));
}
}
break;
case depset::EK_DECL:

View file

@ -0,0 +1,5 @@
// PR 99245 ICE writing out user of type_info
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
namespace std { class type_info {}; }

View file

@ -0,0 +1,9 @@
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
namespace std { class type_info; }
import "pr99245_a.H";
namespace std {
const type_info* __cxa_exception_type () noexcept;
}