From 8c4137c7ead515baaf1ac8340edeb3a442388b5b Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 12 Feb 2021 08:43:09 -0800 Subject: [PATCH] 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. --- gcc/cp/module.cc | 36 ++++++++++++++++++++---- gcc/testsuite/g++.dg/modules/pr99039_a.C | 9 ++++++ gcc/testsuite/g++.dg/modules/pr99039_b.C | 9 ++++++ 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/pr99039_a.C create mode 100644 gcc/testsuite/g++.dg/modules/pr99039_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 37ccddc74a5..520494f2543 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 00000000000..56041e948db --- /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 00000000000..6fb76f584fa --- /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; +} -- 2.30.2