aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-09-04 16:14:28 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-09-04 14:14:28 +0000
commit61a74079b01d0229d95f14d160bcbe6c4f88147f (patch)
tree37a2f18b9ddc64a6fda6a6cc4c075c72734d0ce7 /gcc/tree.c
parent24ba81955d92ff8c29f814867b887446f5c0be05 (diff)
downloadgcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.zip
gcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.tar.gz
gcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.tar.bz2
Makefile.in (ipa-devirt.o): Add dependency on diagnostic.h
* Makefile.in (ipa-devirt.o): Add dependency on diagnostic.h * ipa-devirt.c: Include diganostic.h (odr_type_d): Add types and types_set. (hash_type_name): Work for types with vtables during LTO. (odr_hasher::remove): Fix comment; destroy types_set. (add_type_duplicate): New function, (get_odr_type): Use it. (dump_type_inheritance_graph): Dump type duplicates. * ipa.c (symtab_remove_unreachable_nodes): Build type inheritance graph. * tree.c (types_same_for_odr): Give exact answers on types with virtual tables. From-SVN: r202258
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index b469b97..7e44b40 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11853,11 +11853,6 @@ types_same_for_odr (tree type1, tree 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;
@@ -11868,7 +11863,46 @@ types_same_for_odr (tree type1, tree type2)
if (type_in_anonymous_namespace_p (type1)
|| type_in_anonymous_namespace_p (type2))
return false;
+ /* When assembler name of virtual table is available, it is
+ easy to compare types for equivalence. */
+ if (TYPE_BINFO (type1) && TYPE_BINFO (type2)
+ && BINFO_VTABLE (TYPE_BINFO (type1))
+ && BINFO_VTABLE (TYPE_BINFO (type2)))
+ {
+ tree v1 = BINFO_VTABLE (TYPE_BINFO (type1));
+ tree v2 = BINFO_VTABLE (TYPE_BINFO (type2));
+ if (TREE_CODE (v1) == POINTER_PLUS_EXPR)
+ {
+ if (TREE_CODE (v2) != POINTER_PLUS_EXPR
+ || !operand_equal_p (TREE_OPERAND (v1, 1),
+ TREE_OPERAND (v2, 1), 0))
+ return false;
+ v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0);
+ v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0);
+ }
+ v1 = DECL_ASSEMBLER_NAME (v1);
+ v2 = DECL_ASSEMBLER_NAME (v2);
+ /* If we ever start adding random .blah suffixes after
+ assembler names, we need to compare for match ignoring
+ these (and update odr_type_hash, too). */
+#ifdef ENABLE_CHECKING
+ gcc_assert (!strchr (IDENTIFIER_POINTER (v1), '.')
+ && !strchr (IDENTIFIER_POINTER (v2), '.'));
+#endif
+ return (v1 == v2);
+ }
+
+ /* FIXME: the code comparing type names consider all instantiations of the
+ same template to have same name. This is because we have no access
+ to template parameters. For types with no virtual method tables
+ we thus can return false positives. At the moment we do not need
+ to compare types in other scenarios than devirtualization. */
+
+ /* 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;
if (!TYPE_NAME (type1))
return false;
if (!decls_same_for_odr (TYPE_NAME (type1), TYPE_NAME (type2)))