re PR ipa/66223 (Diagnostic of pure virtual function call broken, including __cxa_pure_virtual)

PR ipa/66223
	* ipa-devirt.c (is_cxa_pure_virtual_p): New function.
	(maybe_record_node): Record cxa_pure_virtual as the only possible
	target if there are not ohter candidates.
	(possible_polymorphic_call_target_p): Accept cxa_pure_virtual.

	* g++.dg/ipa/devirt-50.C: New testcase.

From-SVN: r232572
This commit is contained in:
Jan Hubicka 2016-01-19 17:49:50 +01:00 committed by Jan Hubicka
parent b1b6d906cd
commit ceda2c69d5
4 changed files with 64 additions and 2 deletions

View File

@ -1,3 +1,11 @@
2016-01-19 Jan Hubicka <hubicka@ucw.cz>
PR ipa/66223
* ipa-devirt.c (is_cxa_pure_virtual_p): New function.
(maybe_record_node): Record cxa_pure_virtual as the only possible
target if there are not ohter candidates.
(possible_polymorphic_call_target_p): Accept cxa_pure_virtual.
2016-01-19 Richard Biener <rguenther@suse.de> 2016-01-19 Richard Biener <rguenther@suse.de>
* hsa-gen.c (get_memory_order_name): Use MEMMODEL_ constants. * hsa-gen.c (get_memory_order_name): Use MEMMODEL_ constants.

View File

@ -2327,6 +2327,17 @@ referenced_from_vtable_p (struct cgraph_node *node)
return found; return found;
} }
/* Return if TARGET is cxa_pure_virtual. */
static bool
is_cxa_pure_virtual_p (tree target)
{
return target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE
&& DECL_NAME (target)
&& !strcmp (IDENTIFIER_POINTER (DECL_NAME (target)),
"__cxa_pure_virtual");
}
/* If TARGET has associated node, record it in the NODES array. /* If TARGET has associated node, record it in the NODES array.
CAN_REFER specify if program can refer to the target directly. CAN_REFER specify if program can refer to the target directly.
if TARGET is unknown (NULL) or it can not be inserted (for example because if TARGET is unknown (NULL) or it can not be inserted (for example because
@ -2341,11 +2352,12 @@ maybe_record_node (vec <cgraph_node *> &nodes,
{ {
struct cgraph_node *target_node, *alias_target; struct cgraph_node *target_node, *alias_target;
enum availability avail; enum availability avail;
bool pure_virtual = is_cxa_pure_virtual_p (target);
/* cxa_pure_virtual and __builtin_unreachable do not need to be added into /* __builtin_unreachable do not need to be added into
list of targets; the runtime effect of calling them is undefined. list of targets; the runtime effect of calling them is undefined.
Only "real" virtual methods should be accounted. */ Only "real" virtual methods should be accounted. */
if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE) if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE && !pure_virtual)
return; return;
if (!can_refer) if (!can_refer)
@ -2388,6 +2400,7 @@ maybe_record_node (vec <cgraph_node *> &nodes,
??? Maybe it would make sense to be more aggressive for LTO even ??? Maybe it would make sense to be more aggressive for LTO even
elsewhere. */ elsewhere. */
if (!flag_ltrans if (!flag_ltrans
&& !pure_virtual
&& type_in_anonymous_namespace_p (DECL_CONTEXT (target)) && type_in_anonymous_namespace_p (DECL_CONTEXT (target))
&& (!target_node && (!target_node
|| !referenced_from_vtable_p (target_node))) || !referenced_from_vtable_p (target_node)))
@ -2401,6 +2414,20 @@ maybe_record_node (vec <cgraph_node *> &nodes,
{ {
gcc_assert (!target_node->global.inlined_to); gcc_assert (!target_node->global.inlined_to);
gcc_assert (target_node->real_symbol_p ()); gcc_assert (target_node->real_symbol_p ());
/* Only add pure virtual if it is the only possible target. This way
we will preserve the diagnostics about pure virtual called in many
cases without disabling optimization in other. */
if (pure_virtual)
{
if (nodes.length ())
return;
}
/* If we found a real target, take away cxa_pure_virtual. */
else if (!pure_virtual && nodes.length () == 1
&& is_cxa_pure_virtual_p (nodes[0]->decl))
nodes.pop ();
if (pure_virtual && nodes.length ())
return;
if (!inserted->add (target)) if (!inserted->add (target))
{ {
cached_polymorphic_call_targets->add (target_node); cached_polymorphic_call_targets->add (target_node);
@ -3328,6 +3355,9 @@ possible_polymorphic_call_target_p (tree otr_type,
|| fcode == BUILT_IN_TRAP)) || fcode == BUILT_IN_TRAP))
return true; return true;
if (is_cxa_pure_virtual_p (n->decl))
return true;
if (!odr_hash) if (!odr_hash)
return true; return true;
targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final); targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final);

View File

@ -1,3 +1,8 @@
2016-01-19 Jan Hubicka <hubicka@ucw.cz>
PR ipa/66223
* g++.dg/ipa/devirt-50.C: New testcase.
2016-01-19 Marek Polacek <polacek@redhat.com> 2016-01-19 Marek Polacek <polacek@redhat.com>
PR c++/68965 PR c++/68965

View File

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-optimized" } */
struct B {
B* self;
B() : self( this ) { self->f(); }
virtual void f() = 0;
};
struct D : B
{
void f() {}
};
int main()
{
D d;
}
/* { dg-final { scan-tree-dump "cxa_pure_virtual" "optimized"} } */