[gcc r11-7532] c++: Duplicate namespace bindings [PR 99245]

Nathan Sidwell nathan@gcc.gnu.org
Fri Mar 5 20:54:03 GMT 2021


https://gcc.gnu.org/g:9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7

commit r11-7532-g9e64dd6b3f6706de571c6ed3c4b7a8c8b67f22b7
Author: Nathan Sidwell <nathan@acm.org>
Date:   Fri Mar 5 12:49:34 2021 -0800

    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.

Diff:
---
 gcc/cp/module.cc                         | 33 ++++++++++++++++++--------------
 gcc/testsuite/g++.dg/modules/pr99245_a.H |  5 +++++
 gcc/testsuite/g++.dg/modules/pr99245_b.H |  9 +++++++++
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 31bbf9776dd..48862dd9bbc 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 00000000000..94c6bf11995
--- /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 00000000000..548c2720ef5
--- /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;
+}


More information about the Gcc-cvs mailing list