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;