diff mbox series

c++: Seed imported bindings [PR 99039]

Message ID f0df5df0-6358-7094-b4c8-78ec0e669967@acm.org
State New
Headers show
Series c++: Seed imported bindings [PR 99039] | expand

Commit Message

Nathan Sidwell Feb. 12, 2021, 9:31 p.m. UTC
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.
diff mbox series

Patch

diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc
index 37ccddc74a5..520494f2543 100644
--- c/gcc/cp/module.cc
+++ w/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 c/gcc/testsuite/g++.dg/modules/pr99039_a.C w/gcc/testsuite/g++.dg/modules/pr99039_a.C
new file mode 100644
index 00000000000..56041e948db
--- /dev/null
+++ w/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 c/gcc/testsuite/g++.dg/modules/pr99039_b.C w/gcc/testsuite/g++.dg/modules/pr99039_b.C
new file mode 100644
index 00000000000..6fb76f584fa
--- /dev/null
+++ w/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;
+}