aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2016-03-29 21:37:55 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2016-03-29 19:37:55 +0000
commitf8a1abf8e3dc2ef5cb47a13f14e6a7ec8113a46f (patch)
tree0db1268677c278b70680ea23df35ab40f292d64f
parenta362f023e538bc30dd9f2107f71c2435f62b9289 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphclones.c8
-rw-r--r--gcc/coverage.c6
-rw-r--r--gcc/ipa-devirt.c44
-rw-r--r--gcc/symtab.c14
6 files changed, 64 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0427578..866531f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-03-10 Jan Hubicka <hubicka@ucw.cz>
+
+ 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.
+
2016-03-29 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/70429
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index d0345c6..e929285 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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);
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 354655e..07ceb1a 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -512,13 +512,7 @@ clone_function_name_1 (const char *name, const char *suffix)
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);
}
diff --git a/gcc/coverage.c b/gcc/coverage.c
index e3bab61..b1fce7d 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -745,11 +745,7 @@ build_var (tree fn_decl, tree type, int counter)
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;
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
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 523c95d..2d7705e 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -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
+}