diff options
author | Nathan Sidwell <nathan@acm.org> | 2021-03-05 12:49:34 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2021-03-05 12:54:00 -0800 |
commit | 9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7 (patch) | |
tree | b79057eb3e58ba87d4acfcb499b08a20ff59903b /gcc | |
parent | b1bee29167df6b0fbc9a4c8d06e2acbf3367af47 (diff) | |
download | gcc-9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7.zip gcc-9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7.tar.gz gcc-9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/module.cc | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99245_a.H | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99245_b.H | 9 |
3 files changed, 33 insertions, 14 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 31bbf97..48862dd 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -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: diff --git a/gcc/testsuite/g++.dg/modules/pr99245_a.H b/gcc/testsuite/g++.dg/modules/pr99245_a.H new file mode 100644 index 0000000..94c6bf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99245_a.H @@ -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 {}; } diff --git a/gcc/testsuite/g++.dg/modules/pr99245_b.H b/gcc/testsuite/g++.dg/modules/pr99245_b.H new file mode 100644 index 0000000..548c272 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99245_b.H @@ -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; +} |