On 8/14/20 11:04 AM, Jeff Chapman wrote:
Hello!

Attached is a patch that fixes an ICE on the devel/c++-modules branch caused
by a slot invalidation edge case in push_namespace.

I just fell over this myself, reducing a testcase. your fix wasn;t quite right -- we were creating an empty slot in the hash table and then doing another insertion, w/o initializing that slot. We have to also not insert on the first looking.

Thanks for the patch! it was clueful when I hit the problem :)

It's been sitting around for a while and I wasn't sure if I should use the
original date or not. Feel free to adjust that to the commit date if that's
what it should be instead.


2020-05-15  Jeff Chapman II  <jchap...@lock3software.com>

gcc/cp/
        * name-lookup.c (push_namespace): Fix slot invalidation related
        ICE when compiling with modules enabled.

gcc/testsuite/

        * g++.dg/modules/string-view1.C: New test.
        * g++.dg/modules/string-view2.C: Ditto.


Please let me know if there's anything more I can do,
Jeff Chapman II



--
Nathan Sidwell
diff --git c/ChangeLog.modules w/ChangeLog.modules
index 4d50352a698..27233f0228d 100644
--- c/ChangeLog.modules
+++ w/ChangeLog.modules
@@ -1,3 +1,14 @@
+2020-08-27  Nathan Sidwell  <nat...@acm.org>
+	    Jeff Chapman II  <jchap...@lock3software.com>
+
+	Fix hash table breakage.
+	gcc/cp/
+	* name-lookup.c (push_namespace): Do not create slot on first
+	lookup.
+	gcc/testsuite/
+	* g++.dg/modules/string-view1.C: New test.
+	* g++.dg/modules/string-view2.C: Ditto.
+
 2020-08-27  Nathan Sidwell  <nat...@acm.org>
 
 	Merge trunk 708b3600d04.
diff --git c/gcc/cp/name-lookup.c w/gcc/cp/name-lookup.c
index d7ec9d214ed..3e5985d396c 100644
--- c/gcc/cp/name-lookup.c
+++ w/gcc/cp/name-lookup.c
@@ -8872,8 +8872,9 @@ push_namespace (tree name, bool make_inline)
     {
       /* Before making a new namespace, see if we already have one in
 	 the existing partitions of the current namespace.  */
-      tree *slot = find_namespace_slot (current_namespace, name, true);
-      ns = reuse_namespace (slot, current_namespace, name);
+      tree *slot = find_namespace_slot (current_namespace, name, false);
+      if (slot)
+	ns = reuse_namespace (slot, current_namespace, name);
       if (!ns)
 	ns = make_namespace (current_namespace, name,
 			     input_location, make_inline);
@@ -8884,6 +8885,12 @@ push_namespace (tree name, bool make_inline)
 	{
 	  /* finish up making the namespace.  */
 	  add_decl_to_level (NAMESPACE_LEVEL (current_namespace), ns);
+	  if (!slot)
+	    {
+	      slot = find_namespace_slot (current_namespace, name);
+	      /* This should find the slot created by pushdecl.  */
+	      gcc_checking_assert (slot);
+	    }
 	  make_namespace_finish (ns, slot);
 
 	  /* Add the anon using-directive here, we don't do it in
diff --git c/gcc/testsuite/g++.dg/modules/string-view1.C w/gcc/testsuite/g++.dg/modules/string-view1.C
new file mode 100644
index 00000000000..f5391f39180
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/string-view1.C
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fmodules-ts" }
+module;
+#include <cstdio>
+#include <string_view>
+export module foo;
+// { dg-module-cmi foo }
diff --git c/gcc/testsuite/g++.dg/modules/string-view2.C w/gcc/testsuite/g++.dg/modules/string-view2.C
new file mode 100644
index 00000000000..dad30eabba6
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/string-view2.C
@@ -0,0 +1,56 @@
+// { dg-additional-options "-fmodules-ts" }
+// reduced from string-view1 through cvise. Broken under c++2a too.
+// we were creating a hash slot, and then doing another lookup without
+// initializing that first slot :(
+
+namespace std {
+typedef int a;
+int b;
+decltype(nullptr) c;
+namespace xyz {}
+__builtin_va_list d;
+int n;
+int e;
+int f;
+int g;
+int h;
+int i;
+int j;
+int k;
+typedef struct l m;
+typedef struct aa w;
+typedef struct x o;
+typedef x p;
+long q;
+long r;
+typedef l s;
+extern p ab;
+void t();
+void v();
+extern p ac;
+void ad();
+int ae;
+int af;
+extern p ag;
+extern p ah;
+void ai();
+void y();
+int aj;
+int ak;
+int al;
+char am;
+int an;
+a ao;
+int ap;
+int aq;
+void z();
+int ar;
+int as;
+void at();
+void au();
+void av();
+void aw();
+int u;
+namespace zz {
+}
+}

Reply via email to