aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-02-12 08:43:09 -0800
committerNathan Sidwell <nathan@acm.org>2021-02-12 13:50:03 -0800
commit8c4137c7ead515baaf1ac8340edeb3a442388b5b (patch)
treed6ccd7dde1ca9927baaefec183c28bd9619e0546
parent0c27fe96f812df76ca07272d3c68765bd1f9dc08 (diff)
downloadgcc-8c4137c7ead515baaf1ac8340edeb3a442388b5b.zip
gcc-8c4137c7ead515baaf1ac8340edeb3a442388b5b.tar.gz
gcc-8c4137c7ead515baaf1ac8340edeb3a442388b5b.tar.bz2
c++: Seed imported bindings [PR 99039]
As mentioned in 99040's fix, we can get inter-module using decls. If the using decl is the only reference to an import, we'll have failed to seed our imports leading to an assertion failure. The fix is straight-forwards, check binding contents when seeding imports. gcc/cp/ * module.cc (module_state::write_cluster): Check bindings for imported using-decls. gcc/testsuite/ * g++.dg/modules/pr99039_a.C: New. * g++.dg/modules/pr99039_b.C: New.
-rw-r--r--gcc/cp/module.cc36
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99039_a.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99039_b.C9
3 files changed, 48 insertions, 6 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 37ccddc..520494f 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -3108,7 +3108,8 @@ private:
unsigned section;
#if CHECKING_P
int importedness; /* Checker that imports not occurring
- inappropriately. */
+ inappropriately. +ve imports ok,
+ -ve imports not ok. */
#endif
public:
@@ -14632,13 +14633,36 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
{
depset *dep = b->deps[jx];
- if (!dep->is_binding ()
- && dep->is_import () && !TREE_VISITED (dep->get_entity ()))
+ if (dep->is_binding ())
{
- tree import = dep->get_entity ();
+ /* A cross-module using decl could be here. */
+ for (unsigned ix = dep->deps.length (); --ix;)
+ {
+ depset *bind = dep->deps[ix];
+ if (bind->get_entity_kind () == depset::EK_USING
+ && bind->deps[1]->is_import ())
+ {
+ tree import = bind->deps[1]->get_entity ();
+ if (!TREE_VISITED (import))
+ {
+ sec.tree_node (import);
+ dump (dumper::CLUSTER)
+ && dump ("Seeded import %N", import);
+ }
+ }
+ }
+ /* Also check the namespace itself. */
+ dep = dep->deps[0];
+ }
- sec.tree_node (import);
- dump (dumper::CLUSTER) && dump ("Seeded import %N", import);
+ if (dep->is_import ())
+ {
+ tree import = dep->get_entity ();
+ if (!TREE_VISITED (import))
+ {
+ sec.tree_node (import);
+ dump (dumper::CLUSTER) && dump ("Seeded import %N", import);
+ }
}
}
}
diff --git a/gcc/testsuite/g++.dg/modules/pr99039_a.C b/gcc/testsuite/g++.dg/modules/pr99039_a.C
new file mode 100644
index 0000000..56041e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99039_a.C
@@ -0,0 +1,9 @@
+// PR c++/99039
+// { dg-additional-options -fmodules-ts }
+export module format;
+// { dg-module-cmi format }
+
+export namespace NS
+{
+void Format ();
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr99039_b.C b/gcc/testsuite/g++.dg/modules/pr99039_b.C
new file mode 100644
index 0000000..6fb76f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99039_b.C
@@ -0,0 +1,9 @@
+// { dg-additional-options -fmodules-ts }
+export module hello;
+// { dg-module-cmi hello }
+import format;
+
+export namespace NS
+{
+using NS::Format;
+}