Commit bec81025 by Martin Jambor Committed by Martin Jambor

re PR ipa/61540 (internal compiler error in try_make_edge_direct_virtual_call)

2014-06-20  Martin Jambor  <mjambor@suse.cz>

	PR ipa/61540
	* ipa-prop.c (impossible_devirt_target): New function.
	(try_make_edge_direct_virtual_call): Use it, also instead of
	asserting.

testsuite/
        * g++.dg/ipa/pr61540.C: New test.

From-SVN: r211847
parent bf613c02
2014-06-20 Martin Jambor <mjambor@suse.cz>
PR ipa/61540
* ipa-prop.c (impossible_devirt_target): New function.
(try_make_edge_direct_virtual_call): Use it, also instead of
asserting.
2014-06-20 Yury Gribov <y.gribov@samsung.com>
Max Ostapenko <m.ostapenko@partner.samsung.com>
......
......@@ -2912,6 +2912,29 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
return cs;
}
/* Return the target to be used in cases of impossible devirtualization. IE
and target (the latter can be NULL) are dumped when dumping is enabled. */
static tree
impossible_devirt_target (struct cgraph_edge *ie, tree target)
{
if (dump_file)
{
if (target)
fprintf (dump_file,
"Type inconsident devirtualization: %s/%i->%s\n",
ie->caller->name (), ie->caller->order,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
else
fprintf (dump_file,
"No devirtualization target in %s/%i\n",
ie->caller->name (), ie->caller->order);
}
tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
cgraph_get_create_node (new_target);
return new_target;
}
/* Try to find a destination for indirect edge IE that corresponds to a virtual
call based on a formal parameter which is described by jump function JFUNC
and if it can be determined, make it direct and return the direct edge.
......@@ -2946,15 +2969,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
&& DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
|| !possible_polymorphic_call_target_p
(ie, cgraph_get_node (target)))
{
if (dump_file)
fprintf (dump_file,
"Type inconsident devirtualization: %s/%i->%s\n",
ie->caller->name (), ie->caller->order,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
cgraph_get_create_node (target);
}
target = impossible_devirt_target (ie, target);
return ipa_make_edge_direct_to_target (ie, target);
}
}
......@@ -2984,10 +2999,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (targets.length () == 1)
target = targets[0]->decl;
else
{
target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
cgraph_get_create_node (target);
}
target = impossible_devirt_target (ie, NULL_TREE);
}
else
{
......@@ -3002,10 +3014,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (target)
{
#ifdef ENABLE_CHECKING
gcc_assert (possible_polymorphic_call_target_p
(ie, cgraph_get_node (target)));
#endif
if (!possible_polymorphic_call_target_p (ie, cgraph_get_node (target)))
target = impossible_devirt_target (ie, target);
return ipa_make_edge_direct_to_target (ie, target);
}
else
......
2014-06-20 Martin Jambor <mjambor@suse.cz>
PR ipa/61540
* g++.dg/ipa/pr61540.C: New test.
2014-06-20 Yury Gribov <y.gribov@samsung.com>
Max Ostapenko <m.ostapenko@partner.samsung.com>
......
/* { dg-do compile } */
/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp" } */
struct data {
data(int) {}
};
struct top {
virtual int topf() {}
};
struct intermediate: top {
int topf() /* override */ { return 0; }
};
struct child1: top {
void childf()
{
data d(topf());
}
};
struct child2: intermediate {};
void test(top& t)
{
child1& c = static_cast<child1&>(t);
c.childf();
child2 d;
test(d);
}
int main (int argc, char **argv)
{
child1 c;
test (c);
return 0;
}
/* { dg-final { scan-ipa-dump "Type inconsident devirtualization" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
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