diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2016-03-29 21:37:55 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2016-03-29 19:37:55 +0000 |
commit | f8a1abf8e3dc2ef5cb47a13f14e6a7ec8113a46f (patch) | |
tree | 0db1268677c278b70680ea23df35ab40f292d64f /gcc/ipa-devirt.c | |
parent | a362f023e538bc30dd9f2107f71c2435f62b9289 (diff) | |
download | gcc-f8a1abf8e3dc2ef5cb47a13f14e6a7ec8113a46f.zip gcc-f8a1abf8e3dc2ef5cb47a13f14e6a7ec8113a46f.tar.gz gcc-f8a1abf8e3dc2ef5cb47a13f14e6a7ec8113a46f.tar.bz2 |
re PR lto/70283 (bogus vtable mismatch warnings)
PR ipa/70283
* ipa-devirt.c (methods_equal_p): New function.
(compare_virtual_tables): Use it.
* cgraph.h (symbol_table::symbol_suffix_separator): Declare.
* cgraphclones.c (clone_function_name_1): Use
symbol_table::symbol_suffix_separator.
* coverage.c (build_var): Likewise.
* symtab.c (symbol_table::symbol_suffix_separator): New.
From-SVN: r234532
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r-- | gcc/ipa-devirt.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 4df171b..0694951 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -705,6 +705,29 @@ odr_subtypes_equivalent_p (tree t1, tree t2, return odr_types_equivalent_p (t1, t2, false, NULL, visited, loc1, loc2); } +/* Return true if DECL1 and DECL2 are identical methods. Consider + name equivalent to name.localalias.xyz. */ + +static bool +methods_equal_p (tree decl1, tree decl2) +{ + if (DECL_ASSEMBLER_NAME (decl1) == DECL_ASSEMBLER_NAME (decl2)) + return true; + const char sep = symbol_table::symbol_suffix_separator (); + + const char *name1 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl1)); + const char *ptr1 = strchr (name1, sep); + int len1 = ptr1 ? ptr1 - name1 : strlen (name1); + + const char *name2 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl2)); + const char *ptr2 = strchr (name2, sep); + int len2 = ptr2 ? ptr2 - name2 : strlen (name2); + + if (len1 != len2) + return false; + return !strncmp (name1, name2, len1); +} + /* Compare two virtual tables, PREVAILING and VTABLE and output ODR violation warnings. */ @@ -758,8 +781,8 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) accept the other case. */ while (!end2 && (end1 - || (DECL_ASSEMBLER_NAME (ref1->referred->decl) - != DECL_ASSEMBLER_NAME (ref2->referred->decl) + || (methods_equal_p (ref1->referred->decl, + ref2->referred->decl) && TREE_CODE (ref1->referred->decl) == FUNCTION_DECL)) && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) { @@ -785,8 +808,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) } while (!end1 && (end2 - || (DECL_ASSEMBLER_NAME (ref2->referred->decl) - != DECL_ASSEMBLER_NAME (ref1->referred->decl) + || (methods_equal_p (ref2->referred->decl, ref1->referred->decl) && TREE_CODE (ref2->referred->decl) == FUNCTION_DECL)) && TREE_CODE (ref1->referred->decl) != FUNCTION_DECL) { @@ -823,8 +845,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) if (!end1 && !end2) { - if (DECL_ASSEMBLER_NAME (ref1->referred->decl) - == DECL_ASSEMBLER_NAME (ref2->referred->decl)) + if (methods_equal_p (ref1->referred->decl, ref2->referred->decl)) continue; class_type->odr_violated = true; @@ -920,11 +941,14 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) "unit"); gcc_assert (TREE_CODE (ref2->referred->decl) == FUNCTION_DECL); - inform (DECL_SOURCE_LOCATION (ref1->referred->decl), - "virtual method %qD", ref1->referred->decl); - inform (DECL_SOURCE_LOCATION (ref2->referred->decl), + inform (DECL_SOURCE_LOCATION + (ref1->referred->ultimate_alias_target ()->decl), + "virtual method %qD", + ref1->referred->ultimate_alias_target ()->decl); + inform (DECL_SOURCE_LOCATION + (ref2->referred->ultimate_alias_target ()->decl), "ought to match virtual method %qD but does not", - ref2->referred->decl); + ref2->referred->ultimate_alias_target ()->decl); } else inform (DECL_SOURCE_LOCATION |