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
This commit is contained in:
parent
e022edafa0
commit
b0845a1e51
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
164
gcc/tree.c
164
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 <tree> (t));
|
||||
internal_error ("verify_type failed");
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-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 *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user