diff mbox

[C] fix for ICE with -g

Message ID CABXYE2WoVcwGC_fU_F9QF9GS0i7ikKzqqYb+H7EWs9_ce_FFSA@mail.gmail.com
State New
Headers show

Commit Message

Jim Wilson Oct. 28, 2015, 5:01 p.m. UTC
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
diff mbox

Patch

Index: gcc/c/ChangeLog
===================================================================
--- gcc/c/ChangeLog	(revision 229395)
+++ gcc/c/ChangeLog	(working copy)
@@ -1,3 +1,9 @@ 
+2015-10-26  Jim Wilson  <jim.wilson@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  <rguenther@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.wilson@linaro.org>
+
+	PR debug/66068
+	* gcc.dg/debug/pr66068.c: New test.
+
 2015-10-26  Louis Krupp  <louis.krupp@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
+{
+};