aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-03-05 12:49:34 -0800
committerNathan Sidwell <nathan@acm.org>2021-03-05 12:54:00 -0800
commit9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7 (patch)
treeb79057eb3e58ba87d4acfcb499b08a20ff59903b /gcc
parentb1bee29167df6b0fbc9a4c8d06e2acbf3367af47 (diff)
downloadgcc-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.cc33
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99245_a.H5
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99245_b.H9
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;
+}