re PR lto/70283 (bogus vtable mismatch warnings)
authorJan Hubicka <hubicka@ucw.cz>
Tue, 29 Mar 2016 19:37:55 +0000 (21:37 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 29 Mar 2016 19:37:55 +0000 (19:37 +0000)
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

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphclones.c
gcc/coverage.c
gcc/ipa-devirt.c
gcc/symtab.c

index 042757895d66db6cc888d97b16184372536566c1..866531fe021442daab0d2f14283fd889eee86a3e 100644 (file)
@@ -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
index d0345c698c5139b2409c84da6ad02e5c5134c404..e92928523992b1913d80f028a346fcc8f633f479 100644 (file)
@@ -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 354655e85d20d900ca052005b2d3a0217f966518..07ceb1a80d49dcf3c940f2b0f265996f7b072e00 100644 (file)
@@ -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);
 }
index e3bab61f4b61d3466e394baa2b02bf0146280bb5..b1fce7d0e7a462ef94c8973aab2bc43f5113bd0d 100644 (file)
@@ -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;
index 4df171bc11607b29304e82be7e94d2a0d57c2f5a..069495105bfb368f4d87c7369fb09cccf7d55784 100644 (file)
@@ -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
index 523c95dd29eaa5ab228f6ea7e9721f05949b3b27..2d7705e657cb1e798ac739b2fc964caefc2194b2 100644 (file)
@@ -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
+}