The problem here is that we're trying to compare the TYPE_FIELDS of two variants of an incomplete type, which doesn't make sense; we shouldn't expect TYPE_FIELDS of an incomplete type to be meaningful.

Tested x86_64-pc-linux-gnu.  OK for trunk?
commit c6f5cd55d0bbebc2fa46628ebb8fdec2a44abf3a
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Nov 25 10:47:03 2015 -0500

    	PR middle-end/66214
    
    	* tree.c (gimple_canonical_types_compatible_p) [RECORD_TYPE]:
    	Don't try to compare the fields of incomplete types.

diff --git a/gcc/testsuite/g++.dg/debug/pr66214.C b/gcc/testsuite/g++.dg/debug/pr66214.C
new file mode 100644
index 0000000..79975b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/pr66214.C
@@ -0,0 +1,10 @@
+// PR middle-end/66214
+
+typedef struct bn_gencb_st BN_GENCB;
+
+struct bn_gencb_st {
+  void *arg;
+  union U {
+    int (*cb_2)(int, int, BN_GENCB *);
+  };
+};
diff --git a/gcc/tree.c b/gcc/tree.c
index 2387deb..e918e1b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -13424,6 +13424,11 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
       {
 	tree f1, f2;
 
+	/* Don't try to compare variants of an incomplete type, before
+	   TYPE_FIELDS has been copied around.  */
+	if (!COMPLETE_TYPE_P (t1) && !COMPLETE_TYPE_P (t2))
+	  return true;
+
 	if (TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2))
 	  return false;
 

Reply via email to