Message ID | 20140515144511.GJ30762@virgil.suse |
---|---|
State | New |
Headers | show |
On Thu, May 15, 2014 at 4:45 PM, Martin Jambor <mjambor@suse.cz> wrote: > 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? Ok. Thanks, Richard. > Thanks, > > Martin > > > 2014-05-15 Martin Jambor <mjambor@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; > +}
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; +}