From 11f07ef37786d10517121fc6226681cd1aa2aea2 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 18 Dec 2020 10:07:28 +0100
Subject: [PATCH] c++: Fix PCH ICE with __builtin_source_location [PR98343]

Seems the ggc_remove ppc_nx 3 operand member relies on the hash tables to
contain pointers in the first element, which is not the case for
source_location_table* hash table, which has location_t and unsigned as
first two members and pointer somewhere else.
I've tried to change:
   static void
   pch_nx (T &p, gt_pointer_operator op, void *cookie)
   {
-    op (&p, cookie);
+    extern void gt_pch_nx (T *, gt_pointer_operator, void *);
+    gt_pch_nx (&p, op, cookie);
   }
in hash-traits.h, but that failed miserably.
So, this patch instead overrides the two pch_nx overloads (only the second
one is needed, the former one is identical to the ggc_remove one) but I need
to override both.

2020-12-18  Jakub Jelinek  <jakub@redhat.com>

	PR c++/98343
	* cp-gimplify.c (source_location_table_entry_hash::pch_nx): Override
	static member functions from ggc_remove.

	* g++.dg/pch/pr98343.C: New test.
	* g++.dg/pch/pr98343.Hs: New file.
---
 gcc/cp/cp-gimplify.c                | 15 +++++++++++++++
 gcc/testsuite/g++.dg/pch/pr98343.C  |  6 ++++++
 gcc/testsuite/g++.dg/pch/pr98343.Hs | 18 ++++++++++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/pch/pr98343.C
 create mode 100644 gcc/testsuite/g++.dg/pch/pr98343.Hs

diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 4f62398dfb03..110d25ea1dba 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -2931,6 +2931,21 @@ struct source_location_table_entry_hash
 	    && ref.uid == 0
 	    && ref.var == NULL_TREE);
   }
+
+  static void
+  pch_nx (source_location_table_entry &p)
+  {
+    extern void gt_pch_nx (source_location_table_entry &);
+    gt_pch_nx (p);
+  }
+
+  static void
+  pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
+  {
+    extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
+			   void *);
+    gt_pch_nx (&p, op, cookie);
+  }
 };
 
 static GTY(()) hash_table <source_location_table_entry_hash>
diff --git a/gcc/testsuite/g++.dg/pch/pr98343.C b/gcc/testsuite/g++.dg/pch/pr98343.C
new file mode 100644
index 000000000000..095a4f12d676
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr98343.C
@@ -0,0 +1,6 @@
+// PR c++/98343
+// { dg-options "-std=c++2a" }
+
+#include "pr98343.H"
+
+const void *ptr2 = __builtin_source_location ();
diff --git a/gcc/testsuite/g++.dg/pch/pr98343.Hs b/gcc/testsuite/g++.dg/pch/pr98343.Hs
new file mode 100644
index 000000000000..33c8542e365e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr98343.Hs
@@ -0,0 +1,18 @@
+// PR c++/98343
+// { dg-options "-std=c++2a" }
+
+namespace std
+{
+  struct source_location
+  {
+    struct __impl
+    {
+      const char* _M_file_name;
+      const char* _M_function_name;
+      unsigned _M_line;
+      unsigned _M_column;
+    };
+    const __impl* _M_impl;
+  };
+}
+const void *ptr = __builtin_source_location ();
-- 
GitLab