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:
parent
bc6ad87f60
commit
d84db1ed8a
4 changed files with 136 additions and 3 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
126
gcc/tree.c
126
gcc/tree.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue