dwarf2out.c (gen_type_die_with_usage): Call verify_type.
authorJan Hubicka <hubicka@gcc.gnu.org>
Thu, 30 Apr 2015 02:45:54 +0000 (02:45 +0000)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 30 Apr 2015 02:45:54 +0000 (02:45 +0000)
* dwarf2out.c (gen_type_die_with_usage): Call verify_type.
* ipa-chkp.c (chkp_copy_function_type_adding_bounds): Do not produce
bugus variants.
* tree.c: Include print-tree.h and ipa-utils.h
(free_lang_data_in_type): Clear TYPE_VFIELD leaked by C FE.
(free_lang_data_in_cgraph): Call verify_type.
(verify_type_variant): New function.
(verify_type): New function.
* tree.h (verify_type): Declare.

* lto.c (lto_fixup_state): Call verify_type.

From-SVN: r222606

gcc/ChangeLog
gcc/dwarf2out.c
gcc/ipa-chkp.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/tree.c
gcc/tree.h

index a57bcf6..9dae922 100644 (file)
@@ -1,3 +1,15 @@
+2015-04-29  Jan Hubicka  <hubicka@ucw.cz>
+
+       * dwarf2out.c (gen_type_die_with_usage): Call verify_type.
+       * ipa-chkp.c (chkp_copy_function_type_adding_bounds): Do not produce
+       bugus variants.
+       * tree.c: Include print-tree.h and ipa-utils.h
+       (free_lang_data_in_type): Clear TYPE_VFIELD leaked by C FE.
+       (free_lang_data_in_cgraph): Call verify_type.
+       (verify_type_variant): New function.
+       (verify_type): New function.
+       * tree.h (verify_type): Declare.
+
 2015-04-29  Steve Ellcey  <sellcey@imgtec.com>
 
        * config/mips/mips-cpus.def: (mips4): Change default processor
index 8591cd7..8d5c062 100644 (file)
@@ -20238,6 +20238,11 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
+#ifdef ENABLE_CHECKING
+  if (type)
+     verify_type (type);
+#endif
+
   if (TYPE_NAME (type) != NULL_TREE
       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
       && is_redundant_typedef (TYPE_NAME (type))
index 03abab5..23e08cb 100644 (file)
@@ -244,7 +244,7 @@ tree
 chkp_copy_function_type_adding_bounds (tree orig_type)
 {
   tree type;
-  tree arg_type, attrs, t;
+  tree arg_type, attrs;
   unsigned len = list_length (TYPE_ARG_TYPES (orig_type));
   unsigned *indexes = XALLOCAVEC (unsigned, len);
   unsigned idx = 0, new_idx = 0;
@@ -327,20 +327,6 @@ chkp_copy_function_type_adding_bounds (tree orig_type)
       TYPE_ATTRIBUTES (type) = attrs;
     }
 
-  t = TYPE_MAIN_VARIANT (orig_type);
-  if (orig_type != t)
-    {
-      TYPE_MAIN_VARIANT (type) = t;
-      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t);
-      TYPE_NEXT_VARIANT (t) = type;
-    }
-  else
-    {
-      TYPE_MAIN_VARIANT (type) = type;
-      TYPE_NEXT_VARIANT (type) = NULL;
-    }
-
-
   return type;
 }
 
index 0815e58..ff8a213 100644 (file)
@@ -1,6 +1,10 @@
+2015-04-29  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto.c (lto_fixup_state): Call verify_type.
+
 2015-04-18  Trevor Saunders  <tsaunders@mozilla.com>
 
-       *       lto.c: Adjust for hash_table changes.
+       * lto.c: Adjust for hash_table changes.
 
 2015-03-27  Jan Hubicka  <hubicka@ucw.cz>
 
index f3458c7..4b4005b 100644 (file)
@@ -2844,6 +2844,10 @@ lto_fixup_state (struct lto_in_decl_state *state)
       for (i = 0; i < vec_safe_length (trees); i++)
        {
          tree t = (*trees)[i];
+#ifdef ENABLE_CHECKING
+         if (TYPE_P (t))
+           verify_type (t);
+#endif
          if (VAR_OR_FUNCTION_DECL_P (t)
              && (TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
            (*trees)[i] = lto_symtab_prevailing_decl (t);
index daf0292..a597d52 100644 (file)
@@ -102,6 +102,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "debug.h"
 #include "intl.h"
 #include "builtins.h"
+#include "print-tree.h"
+#include "ipa-utils.h"
 
 /* Tree code classes.  */
 
@@ -5077,6 +5079,11 @@ free_lang_data_in_type (tree type)
       else
        TYPE_FIELDS (type) = NULL_TREE;
 
+      /* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
+        and danagle the pointer from time to time.  */
+      if (TYPE_VFIELD (type) && TREE_CODE (TYPE_VFIELD (type)) != FIELD_DECL)
+        TYPE_VFIELD (type) = NULL_TREE;
+
       TYPE_METHODS (type) = NULL_TREE;
       if (TYPE_BINFO (type))
        {
@@ -5784,6 +5791,10 @@ free_lang_data_in_cgraph (void)
   /* Traverse every type found freeing its language data.  */
   FOR_EACH_VEC_ELT (fld.types, i, t)
     free_lang_data_in_type (t);
+#ifdef ENABLE_CHECKING
+  FOR_EACH_VEC_ELT (fld.types, i, t)
+    verify_type (t);
+#endif
 
   delete fld.pset;
   fld.worklist.release ();
@@ -12425,4 +12436,157 @@ element_mode (const_tree t)
   return TYPE_MODE (t);
 }
 
+/* Veirfy that basic properties of T match TV and thus T can be a variant of
+   TV.  TV should be the more specified variant (i.e. the main variant).  */
+
+static bool
+verify_type_variant (const_tree t, tree tv)
+{
+  if (TREE_CODE (t) != TREE_CODE (tv))
+    {
+      error ("type variant has different TREE_CODE");
+      debug_tree (tv);
+      return false;
+    }
+  if (COMPLETE_TYPE_P (t) && TYPE_SIZE (t) != TYPE_SIZE (tv))
+    {
+      error ("type variant has different TYPE_SIZE");
+      debug_tree (tv);
+      error ("type variant's TYPE_SIZE");
+      debug_tree (TYPE_SIZE (tv));
+      error ("type's TYPE_SIZE");
+      debug_tree (TYPE_SIZE (t));
+      return false;
+    }
+  if (COMPLETE_TYPE_P (t)
+      && TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv)
+      /* FIXME: ideally we should compare pointer equality, but java FE produce
+        variants where size is INTEGER_CST of different type (int wrt size_type)
+        during libjava biuld.  */
+      && !operand_equal_p (TYPE_SIZE_UNIT (t), TYPE_SIZE_UNIT (tv), 0))
+    {
+      error ("type variant has different TYPE_SIZE_UNIT");
+      debug_tree (tv);
+      error ("type variant's TYPE_SIZE_UNIT");
+      debug_tree (TYPE_SIZE_UNIT (tv));
+      error ("type's TYPE_SIZE_UNIT");
+      debug_tree (TYPE_SIZE_UNIT (t));
+      return false;
+    }
+  /* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
+     and danagle the pointer from time to time.  */
+  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_VFIELD (t) != TYPE_VFIELD (tv)
+      && (!TYPE_VFIELD (tv) || TREE_CODE (TYPE_VFIELD (tv)) != TREE_LIST))
+    {
+      error ("type variant has different TYPE_VFIELD");
+      debug_tree (tv);
+      return false;
+    }
+  if (((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
+       || TREE_CODE (t) == INTEGER_TYPE
+       || TREE_CODE (t) == BOOLEAN_TYPE
+       || TREE_CODE (t) == REAL_TYPE
+       || TREE_CODE (t) == FIXED_POINT_TYPE)
+       && (TYPE_MAX_VALUE (t) != TYPE_MAX_VALUE (tv)
+          || TYPE_MIN_VALUE (t) != TYPE_MIN_VALUE (tv)))
+    {
+      error ("type variant has different TYPE_MAX_VALUE or TYPE_MIN_VALUE");
+      debug_tree (tv);
+      return false;
+    }
+  if (TREE_CODE (t) == METHOD_TYPE
+      && TYPE_METHOD_BASETYPE (t) != TYPE_METHOD_BASETYPE (tv))
+    {
+      error ("type variant has different TYPE_METHOD_BASETYPE");
+      debug_tree (tv);
+      return false;
+    }
+  /* FIXME: this check triggers during libstdc++ build that is a bug.
+     It affects non-LTO debug output only, because free_lang_data clears
+     this anyway.  */
+  if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0
+      && TYPE_METHODS (t) != TYPE_METHODS (tv))
+    {
+      error ("type variant has different TYPE_METHODS");
+      debug_tree (tv);
+      return false;
+    }
+  if (TREE_CODE (t) == OFFSET_TYPE
+      && TYPE_OFFSET_BASETYPE (t) != TYPE_OFFSET_BASETYPE (tv))
+    {
+      error ("type variant has different TYPE_OFFSET_BASETYPE");
+      debug_tree (tv);
+      return false;
+    }
+  if (TREE_CODE (t) == ARRAY_TYPE
+      && TYPE_ARRAY_MAX_SIZE (t) != TYPE_ARRAY_MAX_SIZE (tv))
+    {
+      error ("type variant has different TYPE_ARRAY_MAX_SIZE");
+      debug_tree (tv);
+      return false;
+    }
+  /* FIXME: Be lax and allow TYPE_BINFO to be missing in variant types
+     or even type's main variant.  This is needed to make bootstrap pass
+     and the bug seems new in GCC 5.
+     C++ FE should be updated to make this consistent and we should check
+     that TYPE_BINFO is always NULL for !COMPLETE_TYPE_P and otherwise there
+     is a match with main variant.
+
+     Also disable the check for Java for now because of parser hack that builds
+     first an dummy BINFO and then sometimes replace it by real BINFO in some
+     of the copies.  */
+  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t) && TYPE_BINFO (tv)
+      && TYPE_BINFO (t) != TYPE_BINFO (tv)
+      /* FIXME: Java sometimes keep dump TYPE_BINFOs on variant types.
+        Since there is no cheap way to tell C++/Java type w/o LTO, do checking
+        at LTO time only.  */
+      && (in_lto_p && odr_type_p (t)))
+    {
+      error ("type variant has different TYPE_BINFO");
+      debug_tree (tv);
+      error ("type variant's TYPE_BINFO");
+      debug_tree (TYPE_BINFO (tv));
+      error ("type's TYPE_BINFO");
+      debug_tree (TYPE_BINFO (t));
+      return false;
+    }
+  return true;
+}
+
+/* Verify type T.  */
+
+void
+verify_type (const_tree t)
+{
+  bool error_found = false;
+  tree mv = TYPE_MAIN_VARIANT (t);
+  if (!mv)
+    {
+      error ("Main variant is not defined");
+      error_found = true;
+    }
+  else if (mv != TYPE_MAIN_VARIANT (mv))
+    {
+      error ("TYPE_MAIN_VARIANT has different TYPE_MAIN_VARIANT");
+      debug_tree (mv);
+      error_found = true;
+    }
+  else if (t != mv && !verify_type_variant (t, mv))
+    error_found = true;
+  /* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
+     and danagle the pointer from time to time.  */
+  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_VFIELD (t)
+      && TREE_CODE (TYPE_VFIELD (t)) != FIELD_DECL
+      && TREE_CODE (TYPE_VFIELD (t)) != TREE_LIST)
+    {
+      error ("TYPE_VFIELD is not FIELD_DECL nor TREE_LIST");
+      debug_tree (TYPE_VFIELD (t));
+    }
+  if (error_found)
+    {
+      debug_tree (const_cast <tree> (t));
+      internal_error ("verify_type failed");
+    }
+}
+
 #include "gt-tree.h"
index e17bd9b..1974186 100644 (file)
@@ -4501,6 +4501,7 @@ extern tree drop_tree_overflow (tree);
 extern int tree_map_base_eq (const void *, const void *);
 extern unsigned int tree_map_base_hash (const void *);
 extern int tree_map_base_marked_p (const void *);
+extern void DEBUG_FUNCTION verify_type (const_tree t);
 
 #define tree_map_eq tree_map_base_eq
 extern unsigned int tree_map_hash (const void *);