gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Use types_same_for_odr.

* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Use
	types_same_for_odr.
	* tree.c (decls_same_for_odr): New function.
	(same_for_edr): New function.
	(types_same_for_odr): New function.
	(get_binfo_at_offset): Use it.
	* tree.h (types_same_for_odr): Declare.

From-SVN: r200288
This commit is contained in:
Jan Hubicka 2013-06-21 08:43:39 +02:00 committed by Jan Hubicka
parent bc6ad87f60
commit d84db1ed8a
4 changed files with 136 additions and 3 deletions

View file

@ -1,3 +1,13 @@
2013-06-20 Jan Hubicka <jh@suse.cz>
* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Use
types_same_for_odr.
* tree.c (decls_same_for_odr): New function.
(same_for_edr): New function.
(types_same_for_odr): New function.
(get_binfo_at_offset): Use it.
* tree.h (types_same_for_odr): Declare.
2013-06-20 Oleg Endo <oleg.endo@t-online.de>
Jason Merrill <jason@redhat.com>

View file

@ -1038,7 +1038,7 @@ gimple_extract_devirt_binfo_from_cst (tree cst)
HOST_WIDE_INT pos, size;
tree fld;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (expected_type))
if (types_same_for_odr (type, expected_type))
break;
if (offset < 0)
return NULL_TREE;

View file

@ -218,6 +218,7 @@ static void print_value_expr_statistics (void);
static int type_hash_marked_p (const void *);
static unsigned int type_hash_list (const_tree, hashval_t);
static unsigned int attribute_hash_list (const_tree, hashval_t);
static bool decls_same_for_odr (tree decl1, tree decl2);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
@ -11711,6 +11712,127 @@ lhd_gcc_personality (void)
return gcc_eh_personality_decl;
}
/* For languages with One Definition Rule, work out if
trees are actually the same even if the tree representation
differs. This handles only decls appearing in TYPE_NAME
and TYPE_CONTEXT. That is NAMESPACE_DECL, TYPE_DECL,
RECORD_TYPE and IDENTIFIER_NODE. */
static bool
same_for_odr (tree t1, tree t2)
{
if (t1 == t2)
return true;
if (!t1 || !t2)
return false;
/* C and C++ FEs differ by using IDENTIFIER_NODE and TYPE_DECL. */
if (TREE_CODE (t1) == IDENTIFIER_NODE
&& TREE_CODE (t2) == TYPE_DECL
&& DECL_FILE_SCOPE_P (t1))
{
t2 = DECL_NAME (t2);
gcc_assert (TREE_CODE (t2) == IDENTIFIER_NODE);
}
if (TREE_CODE (t2) == IDENTIFIER_NODE
&& TREE_CODE (t1) == TYPE_DECL
&& DECL_FILE_SCOPE_P (t2))
{
t1 = DECL_NAME (t1);
gcc_assert (TREE_CODE (t1) == IDENTIFIER_NODE);
}
if (TREE_CODE (t1) != TREE_CODE (t2))
return false;
if (TYPE_P (t1))
return types_same_for_odr (t1, t2);
if (DECL_P (t1))
return decls_same_for_odr (t1, t2);
return false;
}
/* For languages with One Definition Rule, work out if
decls are actually the same even if the tree representation
differs. This handles only decls appearing in TYPE_NAME
and TYPE_CONTEXT. That is NAMESPACE_DECL, TYPE_DECL,
RECORD_TYPE and IDENTIFIER_NODE. */
static bool
decls_same_for_odr (tree decl1, tree decl2)
{
if (decl1 && TREE_CODE (decl1) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (decl1))
decl1 = DECL_ORIGINAL_TYPE (decl1);
if (decl2 && TREE_CODE (decl2) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (decl2))
decl2 = DECL_ORIGINAL_TYPE (decl2);
if (decl1 == decl2)
return true;
if (!decl1 || !decl2)
return false;
gcc_checking_assert (DECL_P (decl1) && DECL_P (decl2));
if (TREE_CODE (decl1) != TREE_CODE (decl2))
return false;
if (TREE_CODE (decl1) == TRANSLATION_UNIT_DECL)
return true;
if (TREE_CODE (decl1) != NAMESPACE_DECL
&& TREE_CODE (decl1) != TYPE_DECL)
return false;
if (!DECL_NAME (decl1))
return false;
gcc_checking_assert (TREE_CODE (DECL_NAME (decl1)) == IDENTIFIER_NODE);
gcc_checking_assert (!DECL_NAME (decl2)
|| TREE_CODE (DECL_NAME (decl2)) == IDENTIFIER_NODE);
if (DECL_NAME (decl1) != DECL_NAME (decl2))
return false;
return same_for_odr (DECL_CONTEXT (decl1),
DECL_CONTEXT (decl2));
}
/* For languages with One Definition Rule, work out if
types are same even if the tree representation differs.
This is non-trivial for LTO where minnor differences in
the type representation may have prevented type merging
to merge two copies of otherwise equivalent type. */
bool
types_same_for_odr (tree type1, tree type2)
{
gcc_checking_assert (TYPE_P (type1) && TYPE_P (type2));
type1 = TYPE_MAIN_VARIANT (type1);
type2 = TYPE_MAIN_VARIANT (type2);
if (type1 == type2)
return true;
/* If types are not structuraly same, do not bother to contnue.
Match in the remainder of code would mean ODR violation. */
if (!types_compatible_p (type1, type2))
return false;
#ifndef ENABLE_CHECKING
if (!in_lto_p)
return false;
#endif
/* Check for anonymous namespaces. Those have !TREE_PUBLIC
on the corresponding TYPE_STUB_DECL. */
if (TYPE_STUB_DECL (type1) != TYPE_STUB_DECL (type2)
&& (!TYPE_STUB_DECL (type1)
|| !TYPE_STUB_DECL (type2)
|| !TREE_PUBLIC (TYPE_STUB_DECL (type1))
|| !TREE_PUBLIC (TYPE_STUB_DECL (type2))))
return false;
if (!TYPE_NAME (type1))
return false;
if (!decls_same_for_odr (TYPE_NAME (type1), TYPE_NAME (type2)))
return false;
if (!same_for_odr (TYPE_CONTEXT (type1), TYPE_CONTEXT (type2)))
return false;
/* When not in LTO the MAIN_VARIANT check should be the same. */
gcc_assert (in_lto_p);
return true;
}
/* Try to find a base info of BINFO that would have its field decl at offset
OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be
found, return, otherwise return NULL_TREE. */
@ -11726,7 +11848,7 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
tree fld;
int i;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (expected_type))
if (types_same_for_odr (type, expected_type))
return binfo;
if (offset < 0)
return NULL_TREE;
@ -11756,7 +11878,7 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
{
tree base_binfo, found_binfo = NULL_TREE;
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
if (TREE_TYPE (base_binfo) == TREE_TYPE (fld))
if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
{
found_binfo = base_binfo;
break;

View file

@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree);
extern tree block_ultimate_origin (const_tree);
extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
extern bool types_same_for_odr (tree type1, tree type2);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, HOST_WIDE_INT *);
extern bool contains_bitfld_component_ref_p (const_tree);