Commit 56b1f114 by Jan Hubicka Committed by Jan Hubicka

ipa-utils.h (compare_virtual_tables): Declare.

	* ipa-utils.h (compare_virtual_tables): Declare.
	* ipa-devirt.c (odr_subtypes_equivalent_p): New function

	* lto-symtab.c (lto_varpool_replace_node): Call compare_virtual_tables.

From-SVN: r213990
parent aa0a659c
2014-08-14 Jan Hubicka <hubicka@ucw.cz>
* ipa-utils.h (compare_virtual_tables): Declare.
* ipa-devirt.c (odr_subtypes_equivalent_p): New function
2014-08-14 Marek Polacek <polacek@redhat.com> 2014-08-14 Marek Polacek <polacek@redhat.com>
DR 458 DR 458
......
...@@ -485,6 +485,120 @@ odr_subtypes_equivalent_p (tree t1, tree t2, hash_set<tree> *visited) ...@@ -485,6 +485,120 @@ odr_subtypes_equivalent_p (tree t1, tree t2, hash_set<tree> *visited)
return types_same_for_odr (t1, t2); return types_same_for_odr (t1, t2);
} }
/* Compare two virtual tables, PREVAILING and VTABLE and output ODR
violation warings. */
void
compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
{
int n1, n2;
if (DECL_VIRTUAL_P (prevailing->decl) != DECL_VIRTUAL_P (vtable->decl))
{
odr_violation_reported = true;
if (DECL_VIRTUAL_P (prevailing->decl))
{
varpool_node *tmp = prevailing;
prevailing = vtable;
vtable = tmp;
}
if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))),
OPT_Wodr,
"virtual table of type %qD violates one definition rule",
DECL_CONTEXT (vtable->decl)))
inform (DECL_SOURCE_LOCATION (prevailing->decl),
"variable of same assembler name as the virtual table is "
"defined in another translation unit");
return;
}
if (!prevailing->definition || !vtable->definition)
return;
for (n1 = 0, n2 = 0; true; n1++, n2++)
{
struct ipa_ref *ref1, *ref2;
bool end1, end2;
end1 = !prevailing->iterate_reference (n1, ref1);
end2 = !vtable->iterate_reference (n2, ref2);
if (end1 && end2)
return;
if (!end1 && !end2
&& DECL_ASSEMBLER_NAME (ref1->referred->decl)
!= DECL_ASSEMBLER_NAME (ref2->referred->decl)
&& !n2
&& !DECL_VIRTUAL_P (ref2->referred->decl)
&& DECL_VIRTUAL_P (ref1->referred->decl))
{
if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
"virtual table of type %qD contains RTTI information",
DECL_CONTEXT (vtable->decl)))
{
inform (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
"but is prevailed by one without from other translation unit");
inform (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
"RTTI will not work on this type");
}
n2++;
end2 = !vtable->iterate_reference (n2, ref2);
}
if (!end1 && !end2
&& DECL_ASSEMBLER_NAME (ref1->referred->decl)
!= DECL_ASSEMBLER_NAME (ref2->referred->decl)
&& !n1
&& !DECL_VIRTUAL_P (ref1->referred->decl)
&& DECL_VIRTUAL_P (ref2->referred->decl))
{
n1++;
end1 = !vtable->iterate_reference (n1, ref1);
}
if (end1 || end2)
{
if (end1)
{
varpool_node *tmp = prevailing;
prevailing = vtable;
vtable = tmp;
ref1 = ref2;
}
if (warning_at (DECL_SOURCE_LOCATION
(TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
"virtual table of type %qD violates "
"one definition rule",
DECL_CONTEXT (vtable->decl)))
{
inform (DECL_SOURCE_LOCATION
(TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
"the conflicting type defined in another translation "
"unit");
inform (DECL_SOURCE_LOCATION
(TYPE_NAME (DECL_CONTEXT (ref1->referring->decl))),
"contains additional virtual method %qD",
ref1->referred->decl);
}
return;
}
if (DECL_ASSEMBLER_NAME (ref1->referred->decl)
!= DECL_ASSEMBLER_NAME (ref2->referred->decl))
{
if (warning_at (DECL_SOURCE_LOCATION
(TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
"virtual table of type %qD violates "
"one definition rule ",
DECL_CONTEXT (vtable->decl)))
{
inform (DECL_SOURCE_LOCATION
(TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
"the conflicting type defined in another translation "
"unit");
inform (DECL_SOURCE_LOCATION (ref1->referred->decl),
"virtual method %qD", ref1->referred->decl);
inform (DECL_SOURCE_LOCATION (ref2->referred->decl),
"ought to match virtual method %qD but does not",
ref2->referred->decl);
return;
}
}
}
}
/* Output ODR violation warning about T1 and T2 with REASON. /* Output ODR violation warning about T1 and T2 with REASON.
Display location of ST1 and ST2 if REASON speaks about field or Display location of ST1 and ST2 if REASON speaks about field or
method of the type. method of the type.
......
...@@ -101,6 +101,7 @@ bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *, ...@@ -101,6 +101,7 @@ bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *,
bool decl_maybe_in_construction_p (tree, tree, gimple, tree); bool decl_maybe_in_construction_p (tree, tree, gimple, tree);
tree vtable_pointer_value_to_binfo (const_tree); tree vtable_pointer_value_to_binfo (const_tree);
bool vtable_pointer_value_to_vtable (const_tree, tree *, unsigned HOST_WIDE_INT *); bool vtable_pointer_value_to_vtable (const_tree, tree *, unsigned HOST_WIDE_INT *);
void compare_virtual_tables (varpool_node *, varpool_node *);
bool contains_polymorphic_type_p (const_tree); bool contains_polymorphic_type_p (const_tree);
/* Return vector containing possible targets of polymorphic call E. /* Return vector containing possible targets of polymorphic call E.
......
2014-08-14 Jan Hubicka <hubicka@ucw.cz>
* lto-symtab.c (lto_varpool_replace_node): Call compare_virtual_tables.
2014-08-14 Richard Biener <rguenther@suse.de> 2014-08-14 Richard Biener <rguenther@suse.de>
PR lto/62067 PR lto/62067
......
...@@ -117,6 +117,10 @@ lto_varpool_replace_node (varpool_node *vnode, ...@@ -117,6 +117,10 @@ lto_varpool_replace_node (varpool_node *vnode,
&& vnode->decl != prevailing_node->decl) && vnode->decl != prevailing_node->decl)
DECL_INITIAL (vnode->decl) = error_mark_node; DECL_INITIAL (vnode->decl) = error_mark_node;
/* Check and report ODR violations on virtual tables. */
if (DECL_VIRTUAL_P (vnode->decl) || DECL_VIRTUAL_P (prevailing_node->decl))
compare_virtual_tables (prevailing_node, vnode);
if (vnode->tls_model != prevailing_node->tls_model) if (vnode->tls_model != prevailing_node->tls_model)
{ {
error_at (DECL_SOURCE_LOCATION (vnode->decl), error_at (DECL_SOURCE_LOCATION (vnode->decl),
......
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