Hi, PR 61085 revealed that I forgot to put a type_preserved check to an important spot, namely to update_indirect_edges_after_inlining, which leads to wrong devirtualization because the function does not ignore jump functions it should.
Fixed thusly, bootstrapped and tested on x86_64-linux on both trunk and the 4.9 branch. OK for both? Thanks, Martin 2014-05-15 Martin Jambor <mjam...@suse.cz> PR ipa/61085 * ipa-prop.c (update_indirect_edges_after_inlining): Check type_preserved flag when the indirect edge is polymorphic. testsuite/ * g++.dg/ipa/pr61085.C: New test. diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index da6ffe8..4f983a6 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2877,16 +2877,20 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, else if (jfunc->type == IPA_JF_PASS_THROUGH && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) { - if (ici->agg_contents - && !ipa_get_jf_pass_through_agg_preserved (jfunc)) + if ((ici->agg_contents + && !ipa_get_jf_pass_through_agg_preserved (jfunc)) + || (ici->polymorphic + && !ipa_get_jf_pass_through_type_preserved (jfunc))) ici->param_index = -1; else ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc); } else if (jfunc->type == IPA_JF_ANCESTOR) { - if (ici->agg_contents - && !ipa_get_jf_ancestor_agg_preserved (jfunc)) + if ((ici->agg_contents + && !ipa_get_jf_ancestor_agg_preserved (jfunc)) + || (ici->polymorphic + && !ipa_get_jf_ancestor_type_preserved (jfunc))) ici->param_index = -1; else { diff --git a/gcc/testsuite/g++.dg/ipa/pr61085.C b/gcc/testsuite/g++.dg/ipa/pr61085.C new file mode 100644 index 0000000..531f59d --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr61085.C @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-early-inlining" } */ + +struct A {}; +struct B : virtual A { + unsigned m_i; + B() : m_i () {} + virtual A *m_virt () + { + return 0; + } + ~B () + { + m_foo (); + while (m_i) + ; + } + void m_foo () + { + m_virt (); + } +}; + +class C : B { + A *m_virt () { + __builtin_abort (); + } +}; + +int main () +{ + C c; +}