[PATCH, PR 61085] Add missing type_preserved check

Richard Biener richard.guenther@gmail.com
Thu May 15 14:52:00 GMT 2014


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;
> +}



More information about the Gcc-patches mailing list