Hi, the following patch converting an assert to a test fixes PR 60600. If we determine that a devirtualization cannot happen, we can now convert the call to builtin_unreachable.
Bootstrapped and tested on x86_64-linux. I have also sucessfully LTO built Firefox with the change. Pre-approved by Honza in bugzilla and thus I will commit it shortly. Thanks, Martin 2014-03-25 Martin Jambor <mjam...@suse.cz> PR ipa/60600 * ipa-cp.c (ipa_get_indirect_edge_target_1): Redirect type inconsistent devirtualizations to __builtin_unreachable. testsuite/ * g++.dg/ipa/pr60600.C: New test. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index b71048a..74042ad 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1639,11 +1639,18 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, return NULL_TREE; target = gimple_get_virt_method_for_binfo (token, binfo); } -#ifdef ENABLE_CHECKING - if (target) - gcc_assert (possible_polymorphic_call_target_p - (ie, cgraph_get_node (target))); -#endif + + if (target && !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); + } return target; } diff --git a/gcc/testsuite/g++.dg/ipa/pr60600.C b/gcc/testsuite/g++.dg/ipa/pr60600.C new file mode 100644 index 0000000..00c368e --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60600.C @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -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); +} + +/* { dg-final { scan-ipa-dump "Type inconsident devirtualization" "cp" } } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */