Hi, this patch fixes bogus warning While building libreoffice we get: /aux/hubicka/libreoffice2/core/sw/source/core/attr/calbck.cxx:27:1: note: virtual method �_ZN2sw16LegacyModifyHintD2Ev.localalias.7� sw::LegacyModifyHint::~LegacyModifyHint() {} ^ /aux/hubicka/libreoffice2/core/sw/source/core/attr/calbck.cxx:27:1: note: ought to match virtual method �__comp_dtor � but does not
While buildilng libreoffice. This patch makes the compare to accept local aliases. Sadly one can't look for alias target because it may get confused by ICF (I think). This patch makes us to strip the .localalias suffix. The patch also fixes the warning to come out right (at least in most cases when ICF did not happen) and commonizes the suffix hanlding. Bootstrapped/regtested x86_64-linux and tested on libreoffice. Honza 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. Index: cgraph.h =================================================================== --- cgraph.h (revision 234516) +++ cgraph.h (working copy) @@ -2173,6 +2173,9 @@ public: FILE* GTY ((skip)) dump_file; + /* Return symbol used to separate symbol name from suffix. */ + static char symbol_suffix_separator (); + private: /* Allocate new callgraph node. */ inline cgraph_node * allocate_cgraph_symbol (void); Index: cgraphclones.c =================================================================== --- cgraphclones.c (revision 234516) +++ cgraphclones.c (working copy) @@ -512,13 +512,7 @@ clone_function_name_1 (const char *name, prefix = XALLOCAVEC (char, len + strlen (suffix) + 2); memcpy (prefix, name, len); strcpy (prefix + len + 1, suffix); -#ifndef NO_DOT_IN_LABEL - prefix[len] = '.'; -#elif !defined NO_DOLLAR_IN_LABEL - prefix[len] = '$'; -#else - prefix[len] = '_'; -#endif + prefix[len] = symbol_table::symbol_suffix_separator (); ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++); return get_identifier (tmp_name); } Index: coverage.c =================================================================== --- coverage.c (revision 234516) +++ coverage.c (working copy) @@ -745,11 +745,7 @@ build_var (tree fn_decl, tree type, int else sprintf (buf, "__gcov%u_", counter); len = strlen (buf); -#ifndef NO_DOT_IN_LABEL - buf[len - 1] = '.'; -#elif !defined NO_DOLLAR_IN_LABEL - buf[len - 1] = '$'; -#endif + buf[len - 1] = symbol_table::symbol_suffix_separator (); memcpy (buf + len, fn_name, fn_name_len + 1); DECL_NAME (var) = get_identifier (buf); TREE_STATIC (var) = 1; Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 234516) +++ ipa-devirt.c (working copy) @@ -705,6 +705,29 @@ odr_subtypes_equivalent_p (tree t1, tree 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 *pr 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 *pr } 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 *pr 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 *pr "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 Index: symtab.c =================================================================== --- symtab.c (revision 234516) +++ symtab.c (working copy) @@ -2137,3 +2137,17 @@ symtab_node::definition_alignment () call_for_symbol_and_aliases (get_alignment_1, &align, true); return align; } + +/* Return symbol used to separate symbol name from suffix. */ + +char +symbol_table::symbol_suffix_separator () +{ +#ifndef NO_DOT_IN_LABEL + return '.'; +#elif !defined NO_DOLLAR_IN_LABEL + return '$'; +#else + return '_'; +#endif +}