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:
Jan Hubicka 2015-04-30 02:45:54 +00:00
parent e022edafa0
commit b0845a1e51
7 changed files with 192 additions and 16 deletions

View 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

View 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))

View 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;
}

View 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>

View 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);

View 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"

View 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 *);