Compiling a simple testcase that defines an incomplete struct/union and then a variant of that type and then completes the struct/union gives an ICE in verify_type.
palantir:2257$ cat tmp.c struct S a; const struct S b; struct S { }; palantir:2258$ ./xgcc -B./ -O -g tmp.c tmp.c:5:1: error: type variant has different TYPE_VFIELD }; ^ ... tmp.c:5:1: internal compiler error: verify_type failed ... The problem is in the C front end. It uses TYPE_VFIELD to keep track of incomplete types via C_TYPE_INCOMPLETE_VARS. This is only valid on the type main variant, and is cleared when the type main variant is completed. When we create a variant type, this field is being copied to the variant along with all other type fields. Since we never look at this field on variant types, it never gets cleared, and we end up with dangling pointers that trigger the ICE in verify_type. So this should be fixed by clearing the field when creating a variant type. Attached is a patch that does this clearing, and adds a testcase. This was tested with an x86_64 linux bootstrap and make check, and also a gdb make check. With this patch, some of the hacks in type_verify to work around the C front-end problem may no longer be necessary. I haven't looked at that. Jim
Index: gcc/c/ChangeLog =================================================================== --- gcc/c/ChangeLog (revision 229395) +++ gcc/c/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2015-10-26 Jim Wilson <jim.wil...@linaro.org> + + PR debug/66068 + * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS + after calling build_qualified_type. + 2015-10-22 Richard Biener <rguent...@suse.de> * c-typeck.c (c_finish_omp_clauses): Properly convert operands Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 229395) +++ gcc/c/c-typeck.c (working copy) @@ -13090,6 +13090,8 @@ c_finish_transaction (location_t loc, tree block, tree c_build_qualified_type (tree type, int type_quals) { + tree var_type; + if (type == error_mark_node) return type; @@ -13146,7 +13148,13 @@ c_build_qualified_type (tree type, int type_quals) type_quals &= ~TYPE_QUAL_RESTRICT; } - return build_qualified_type (type, type_quals); + var_type = build_qualified_type (type, type_quals); + /* A variant type does not inherit the list of incomplete vars from the + type main variant. */ + if (TREE_CODE (var_type) == RECORD_TYPE + || TREE_CODE (var_type) == UNION_TYPE) + C_TYPE_INCOMPLETE_VARS (var_type) = 0; + return var_type; } /* Build a VA_ARG_EXPR for the C parser. */ Index: gcc/testsuite/ChangeLog =================================================================== --- gcc/testsuite/ChangeLog (revision 229395) +++ gcc/testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2015-10-26 Jim Wilson <jim.wil...@linaro.org> + + PR debug/66068 + * gcc.dg/debug/pr66068.c: New test. + 2015-10-26 Louis Krupp <louis.kr...@zoho.com> PR fortran/66056 Index: gcc/testsuite/gcc.dg/debug/pr66068.c =================================================================== --- gcc/testsuite/gcc.dg/debug/pr66068.c (revision 0) +++ gcc/testsuite/gcc.dg/debug/pr66068.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +struct S a; +const struct S b; +struct S +{ +}; + +union U c; +const union U d; +union U +{ +};