From b0845a1e51f8c1f3e9e02049a2407321e22ad0b9 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 30 Apr 2015 02:45:54 +0000 Subject: [PATCH] dwarf2out.c (gen_type_die_with_usage): Call verify_type. * 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 | 12 ++++ gcc/dwarf2out.c | 5 ++ gcc/ipa-chkp.c | 16 +---- gcc/lto/ChangeLog | 6 +- gcc/lto/lto.c | 4 ++ gcc/tree.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree.h | 1 + 7 files changed, 192 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a57bcf688c6..9dae922f5fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-04-29 Jan Hubicka + + * 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 * config/mips/mips-cpus.def: (mips4): Change default processor diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8591cd76f15..8d5c062a315 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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)) diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c index 03abab5641a..23e08cbfc6f 100644 --- a/gcc/ipa-chkp.c +++ b/gcc/ipa-chkp.c @@ -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; } diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 0815e584190..ff8a213ab62 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,6 +1,10 @@ +2015-04-29 Jan Hubicka + + * lto.c (lto_fixup_state): Call verify_type. + 2015-04-18 Trevor Saunders - * lto.c: Adjust for hash_table changes. + * lto.c: Adjust for hash_table changes. 2015-03-27 Jan Hubicka diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index f3458c7a72c..4b4005b4b36 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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); diff --git a/gcc/tree.c b/gcc/tree.c index daf0292127f..a597d52ab7a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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 (t)); + internal_error ("verify_type failed"); + } +} + #include "gt-tree.h" diff --git a/gcc/tree.h b/gcc/tree.h index e17bd9b1109..19741869b48 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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 *); -- 2.30.2