Hi,
this patch does the heavy lifting to check all overriders of TYPE_VALUES_RAW
and TYPE_BINFO.  The only bug noticed is that Java builds BINFOs that are not
associated with the type.  I will fix that incrementally (I am back from China
trip so will now push out individual fixes as I canbe around to deal with
possible fallout). I also noticed that TYPE_FIELDS and TYPE_VALUES
documentation is out of date, will send that separately.

This is not complete checking - the more interesting part is to check that the
values are sane acorss type variants.

Bootstrapped/regtested ppc64-linux, comitted.

Honza

        * tree.c (verify_type): Verify TYPE_BINFO and TYPE_VALUES_RAW.
Index: tree.c
===================================================================
--- tree.c      (revision 222968)
+++ tree.c      (working copy)
@@ -12623,7 +12623,7 @@ verify_type (const_tree t)
     {
       /* FIXME: The following check should pass:
          useless_type_conversion_p (const_cast <tree> (t), TREE_TYPE 
(TYPE_MIN_VALUE (t))
-        bud does not for C sizetypes in LTO.  */
+        but does not for C sizetypes in LTO.  */
     }
   else if (TYPE_MINVAL (t))
     {
@@ -12669,7 +12669,7 @@ verify_type (const_tree t)
     {
       /* FIXME: The following check should pass:
          useless_type_conversion_p (const_cast <tree> (t), TREE_TYPE 
(TYPE_MAX_VALUE (t))
-        bud does not for C sizetypes in LTO.  */
+        but does not for C sizetypes in LTO.  */
     }
   else if (TREE_CODE (t) == ARRAY_TYPE)
     {
@@ -12688,6 +12688,166 @@ verify_type (const_tree t)
       error_found = true;
     }
 
+  /* Check various uses of TYPE_BINFO.  */
+  if (RECORD_OR_UNION_TYPE_P (t))
+    {
+      if (!TYPE_BINFO (t))
+       ;
+      else if (TREE_CODE (TYPE_BINFO (t)) != TREE_BINFO)
+       {
+         error ("TYPE_BINFO is not TREE_BINFO");
+         debug_tree (TYPE_BINFO (t));
+         error_found = true;
+       }
+      /* FIXME: Java builds invalid empty binfos that do not have
+         TREE_TYPE set.  */
+      else if (TREE_TYPE (TYPE_BINFO (t)) != TYPE_MAIN_VARIANT (t) && 0)
+       {
+         error ("TYPE_BINFO type is not TYPE_MAIN_VARIANT");
+         debug_tree (TREE_TYPE (TYPE_BINFO (t)));
+         error_found = true;
+       }
+    }
+  else if (TYPE_LANG_SLOT_1 (t) && in_lto_p)
+    {
+      error ("TYPE_LANG_SLOT_1 (binfo) field is non-NULL");
+      debug_tree (TYPE_LANG_SLOT_1 (t));
+      error_found = true;
+    }
+
+  /* Check various uses of TYPE_VALUES_RAW.  */
+  if (TREE_CODE (t) == ENUMERAL_TYPE)
+    for (tree l = TYPE_VALUES (t); l; l = TREE_CHAIN (l))
+      {
+       tree value = TREE_VALUE (l);
+       tree name = TREE_PURPOSE (l);
+
+       /* C FE porduce INTEGER_CST of INTEGER_TYPE, while C++ FE uses
+          CONST_DECL of ENUMERAL TYPE.  */
+       if (TREE_CODE (value) != INTEGER_CST && TREE_CODE (value) != CONST_DECL)
+         {
+           error ("Enum value is not CONST_DECL or INTEGER_CST");
+           debug_tree (value);
+           debug_tree (name);
+           error_found = true;
+         }
+       if (TREE_CODE (TREE_TYPE (value)) != INTEGER_TYPE
+           && !useless_type_conversion_p (const_cast <tree> (t), TREE_TYPE 
(value)))
+         {
+           error ("Enum value type is not INTEGER_TYPE nor convertible to the 
enum");
+           debug_tree (value);
+           debug_tree (name);
+           error_found = true;
+         }
+       if (TREE_CODE (name) != IDENTIFIER_NODE)
+         {
+           error ("Enum value name is not IDENTIFIER_NODE");
+           debug_tree (value);
+           debug_tree (name);
+           error_found = true;
+         }
+      }
+  else if (TREE_CODE (t) == ARRAY_TYPE)
+    {
+      if (TYPE_DOMAIN (t) && TREE_CODE (TYPE_DOMAIN (t)) != INTEGER_TYPE)
+       {
+         error ("Array TYPE_DOMAIN is not integer type");
+         debug_tree (TYPE_DOMAIN (t));
+         error_found = true;
+       }
+    }
+  else if (RECORD_OR_UNION_TYPE_P (t))
+    for (tree fld = TYPE_FIELDS (t); fld; fld = TREE_CHAIN (fld))
+      {
+       /* TODO: verify properties of decls.  */
+       if (TREE_CODE (fld) == FIELD_DECL)
+         ;
+       else if (TREE_CODE (fld) == TYPE_DECL)
+         ;
+       else if (TREE_CODE (fld) == CONST_DECL)
+         ;
+       else if (TREE_CODE (fld) == VAR_DECL)
+         ;
+       else if (TREE_CODE (fld) == TEMPLATE_DECL)
+         ;
+       else if (TREE_CODE (fld) == USING_DECL)
+         ;
+       else
+         {
+           error ("Wrong tree in TYPE_FIELDS list");
+           debug_tree (fld);
+           error_found = true;
+         }
+      }
+  else if (TREE_CODE (t) == INTEGER_TYPE
+          || TREE_CODE (t) == BOOLEAN_TYPE
+          || TREE_CODE (t) == OFFSET_TYPE
+          || TREE_CODE (t) == REFERENCE_TYPE
+          || TREE_CODE (t) == NULLPTR_TYPE
+          || TREE_CODE (t) == POINTER_TYPE)
+    {
+      if (TYPE_CACHED_VALUES_P (t) != (TYPE_CACHED_VALUES (t) != NULL))
+       {
+         error ("TYPE_CACHED_VALUES_P is %i while TYPE_CACHED_VALUES is %p",
+                TYPE_CACHED_VALUES_P (t), (void *)TYPE_CACHED_VALUES (t));
+         error_found = true;
+       }
+      else if (TYPE_CACHED_VALUES_P (t) && TREE_CODE (TYPE_CACHED_VALUES (t)) 
!= TREE_VEC)
+       {
+         error ("TYPE_CACHED_VALUES is not TREE_VEC");
+         debug_tree (TYPE_CACHED_VALUES (t));
+         error_found = true;
+       }
+      /* Verify just enough of cache to ensure that no one copied it to new 
type.
+        All copying should go by copy_node that should clear it.  */
+      else if (TYPE_CACHED_VALUES_P (t))
+       {
+         int i;
+         for (i = 0; i < TREE_VEC_LENGTH (TYPE_CACHED_VALUES (t)); i++)
+           if (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i)
+               && TREE_TYPE (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i)) != t)
+             {
+               error ("wrong TYPE_CACHED_VALUES entry");
+               debug_tree (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i));
+               error_found = true;
+               break;
+             }
+       }
+    }
+  else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
+    for (tree l = TYPE_ARG_TYPES (t); l; l = TREE_CHAIN (l))
+      {
+       if (TREE_PURPOSE (l))
+         {
+           error ("TREE_PURPOSE is non-NULL in TYPE_ARG_TYPES list");
+           debug_tree (l);
+           error_found = true;
+         }
+       if (!TYPE_P (TREE_VALUE (l)))
+         {
+           error ("Wrong entry in TYPE_ARG_TYPES list");
+           debug_tree (l);
+           error_found = true;
+         }
+      }
+  else if (!is_lang_specific (t) && TYPE_VALUES_RAW (t))
+    {
+      error ("TYPE_VALUES_RAW field is non-NULL");
+      debug_tree (TYPE_VALUES_RAW (t));
+      error_found = true;
+    }
+  if (TREE_CODE (t) != INTEGER_TYPE
+      && TREE_CODE (t) != BOOLEAN_TYPE
+      && TREE_CODE (t) != OFFSET_TYPE
+      && TREE_CODE (t) != REFERENCE_TYPE
+      && TREE_CODE (t) != NULLPTR_TYPE
+      && TREE_CODE (t) != POINTER_TYPE
+      && TYPE_CACHED_VALUES_P (t))
+    {
+      error ("TYPE_CACHED_VALUES_P is set while it should not");
+      error_found = true;
+    }
+
 
   if (error_found)
     {

Reply via email to