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
This commit is contained in:
parent
aa0a659ca6
commit
56b1f114de
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
DR 458
|
||||
|
114
gcc/ipa-devirt.c
114
gcc/ipa-devirt.c
@ -485,6 +485,120 @@ odr_subtypes_equivalent_p (tree t1, tree t2, hash_set<tree> *visited)
|
||||
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.
|
||||
Display location of ST1 and ST2 if REASON speaks about field or
|
||||
method of the type.
|
||||
|
@ -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);
|
||||
tree vtable_pointer_value_to_binfo (const_tree);
|
||||
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);
|
||||
|
||||
/* Return vector containing possible targets of polymorphic call E.
|
||||
|
@ -1,3 +1,7 @@
|
||||
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>
|
||||
|
||||
PR lto/62067
|
||||
|
@ -117,6 +117,10 @@ lto_varpool_replace_node (varpool_node *vnode,
|
||||
&& vnode->decl != prevailing_node->decl)
|
||||
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)
|
||||
{
|
||||
error_at (DECL_SOURCE_LOCATION (vnode->decl),
|
||||
|
Loading…
Reference in New Issue
Block a user