diff options
author | Nathan Sidwell <nathan@acm.org> | 2021-02-12 08:43:09 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2021-02-12 13:50:03 -0800 |
commit | 8c4137c7ead515baaf1ac8340edeb3a442388b5b (patch) | |
tree | d6ccd7dde1ca9927baaefec183c28bd9619e0546 | |
parent | 0c27fe96f812df76ca07272d3c68765bd1f9dc08 (diff) | |
download | gcc-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.cc | 36 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99039_a.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr99039_b.C | 9 |
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; +} |