Commit f8a1abf8 by Jan Hubicka Committed by Jan Hubicka

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
parent a362f023
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> 2016-03-29 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/70429 PR rtl-optimization/70429
......
...@@ -2173,6 +2173,9 @@ public: ...@@ -2173,6 +2173,9 @@ public:
FILE* GTY ((skip)) dump_file; FILE* GTY ((skip)) dump_file;
/* Return symbol used to separate symbol name from suffix. */
static char symbol_suffix_separator ();
private: private:
/* Allocate new callgraph node. */ /* Allocate new callgraph node. */
inline cgraph_node * allocate_cgraph_symbol (void); inline cgraph_node * allocate_cgraph_symbol (void);
......
...@@ -512,13 +512,7 @@ clone_function_name_1 (const char *name, const char *suffix) ...@@ -512,13 +512,7 @@ clone_function_name_1 (const char *name, const char *suffix)
prefix = XALLOCAVEC (char, len + strlen (suffix) + 2); prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
memcpy (prefix, name, len); memcpy (prefix, name, len);
strcpy (prefix + len + 1, suffix); strcpy (prefix + len + 1, suffix);
#ifndef NO_DOT_IN_LABEL prefix[len] = symbol_table::symbol_suffix_separator ();
prefix[len] = '.';
#elif !defined NO_DOLLAR_IN_LABEL
prefix[len] = '$';
#else
prefix[len] = '_';
#endif
ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++); ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
return get_identifier (tmp_name); return get_identifier (tmp_name);
} }
......
...@@ -745,11 +745,7 @@ build_var (tree fn_decl, tree type, int counter) ...@@ -745,11 +745,7 @@ build_var (tree fn_decl, tree type, int counter)
else else
sprintf (buf, "__gcov%u_", counter); sprintf (buf, "__gcov%u_", counter);
len = strlen (buf); len = strlen (buf);
#ifndef NO_DOT_IN_LABEL buf[len - 1] = symbol_table::symbol_suffix_separator ();
buf[len - 1] = '.';
#elif !defined NO_DOLLAR_IN_LABEL
buf[len - 1] = '$';
#endif
memcpy (buf + len, fn_name, fn_name_len + 1); memcpy (buf + len, fn_name, fn_name_len + 1);
DECL_NAME (var) = get_identifier (buf); DECL_NAME (var) = get_identifier (buf);
TREE_STATIC (var) = 1; TREE_STATIC (var) = 1;
......
...@@ -705,6 +705,29 @@ odr_subtypes_equivalent_p (tree t1, tree t2, ...@@ -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 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 /* Compare two virtual tables, PREVAILING and VTABLE and output ODR
violation warnings. */ violation warnings. */
...@@ -758,8 +781,8 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) ...@@ -758,8 +781,8 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
accept the other case. */ accept the other case. */
while (!end2 while (!end2
&& (end1 && (end1
|| (DECL_ASSEMBLER_NAME (ref1->referred->decl) || (methods_equal_p (ref1->referred->decl,
!= DECL_ASSEMBLER_NAME (ref2->referred->decl) ref2->referred->decl)
&& TREE_CODE (ref1->referred->decl) == FUNCTION_DECL)) && TREE_CODE (ref1->referred->decl) == FUNCTION_DECL))
&& TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL)
{ {
...@@ -785,8 +808,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) ...@@ -785,8 +808,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
} }
while (!end1 while (!end1
&& (end2 && (end2
|| (DECL_ASSEMBLER_NAME (ref2->referred->decl) || (methods_equal_p (ref2->referred->decl, ref1->referred->decl)
!= DECL_ASSEMBLER_NAME (ref1->referred->decl)
&& TREE_CODE (ref2->referred->decl) == FUNCTION_DECL)) && TREE_CODE (ref2->referred->decl) == FUNCTION_DECL))
&& TREE_CODE (ref1->referred->decl) != FUNCTION_DECL) && TREE_CODE (ref1->referred->decl) != FUNCTION_DECL)
{ {
...@@ -823,8 +845,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) ...@@ -823,8 +845,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
if (!end1 && !end2) if (!end1 && !end2)
{ {
if (DECL_ASSEMBLER_NAME (ref1->referred->decl) if (methods_equal_p (ref1->referred->decl, ref2->referred->decl))
== DECL_ASSEMBLER_NAME (ref2->referred->decl))
continue; continue;
class_type->odr_violated = true; class_type->odr_violated = true;
...@@ -920,11 +941,14 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) ...@@ -920,11 +941,14 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
"unit"); "unit");
gcc_assert (TREE_CODE (ref2->referred->decl) gcc_assert (TREE_CODE (ref2->referred->decl)
== FUNCTION_DECL); == FUNCTION_DECL);
inform (DECL_SOURCE_LOCATION (ref1->referred->decl), inform (DECL_SOURCE_LOCATION
"virtual method %qD", ref1->referred->decl); (ref1->referred->ultimate_alias_target ()->decl),
inform (DECL_SOURCE_LOCATION (ref2->referred->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", "ought to match virtual method %qD but does not",
ref2->referred->decl); ref2->referred->ultimate_alias_target ()->decl);
} }
else else
inform (DECL_SOURCE_LOCATION inform (DECL_SOURCE_LOCATION
......
...@@ -2137,3 +2137,17 @@ symtab_node::definition_alignment () ...@@ -2137,3 +2137,17 @@ symtab_node::definition_alignment ()
call_for_symbol_and_aliases (get_alignment_1, &align, true); call_for_symbol_and_aliases (get_alignment_1, &align, true);
return align; 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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment