This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix bogus vtable mismatch warnings
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Mar 2016 18:01:59 +0200
- Subject: Fix bogus vtable mismatch warnings
- Authentication-results: sourceware.org; auth=none
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
+}