Hi, the testcase shows a case where try_make_edge_direct_virtual_call disagrees with ipa_get_indirect_edge_target_1 making ipa-inline-transform to ICE on mismatch.
Bootstrapped/regtested x86_64-linux, comitted. Honza Index: ChangeLog =================================================================== --- ChangeLog (revision 219821) +++ ChangeLog (working copy) @@ -1,3 +1,10 @@ +2015-01-18 Jan Hubicka <hubi...@ucw.cz> + + PR ipa/64378 + * ipa-prop.c (try_make_edge_direct_virtual_call): Clear speculative + flag correctly. + * ipa-cp.c (ipa_get_indirect_edge_target_1): Handle speculation. + 2015-01-18 Sandra Loosemore <san...@codesourcery.com> * doc/invoke.texi ([-funroll-loops], [-funroll-all-loops]): Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 219821) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2015-01-18 Jan Hubicka <hubi...@ucw.cz> + + PR ipa/64378 + * g++.dg/torture/pr64378.C: New testcase. + 2015-01-18 Paul Thomas <pa...@gcc.gnu.org> PR fortran/57959 Index: testsuite/g++.dg/torture/pr64378.C =================================================================== --- testsuite/g++.dg/torture/pr64378.C (revision 0) +++ testsuite/g++.dg/torture/pr64378.C (revision 0) @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-fno-ipa-cp" } +struct data { + data(int) {} +}; + +struct top { + virtual int topf() {} +}; + +struct child1: top { + void childf() + { + data d(topf()); + } +}; + +void test(top *t) +{ + child1 *c = static_cast<child1 *>(t); + c->childf(); + child1 d; + test(&d); +} Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 219821) +++ ipa-prop.c (working copy) @@ -2985,7 +2985,7 @@ try_make_edge_direct_virtual_call (struc || !possible_polymorphic_call_target_p (ie, cgraph_node::get (t))) { - /* Do not speculate builtin_unreachable, it is stpid! */ + /* Do not speculate builtin_unreachable, it is stupid! */ if (!ie->indirect_info->vptr_changed) target = ipa_impossible_devirt_target (ie, target); } @@ -3013,6 +3013,7 @@ try_make_edge_direct_virtual_call (struc ctx, &final); if (final && targets.length () <= 1) { + speculative = false; if (targets.length () == 1) target = targets[0]->decl; else Index: ipa-cp.c =================================================================== --- ipa-cp.c (revision 219821) +++ ipa-cp.c (working copy) @@ -1975,8 +1975,13 @@ ipa_get_indirect_edge_target_1 (struct c } } else if (t) - context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type, - anc_offset); + { + context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type, + anc_offset); + if (ie->indirect_info->vptr_changed) + context.possible_dynamic_type_change (ie->in_polymorphic_cdtor, + ie->indirect_info->otr_type); + } else return NULL_TREE;