diff mbox

[PR,61085] Add missing type_preserved check

Message ID 20140515144511.GJ30762@virgil.suse
State New
Headers show

Commit Message

Martin Jambor May 15, 2014, 2:45 p.m. UTC
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  <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.

Comments

Richard Biener May 15, 2014, 2:52 p.m. UTC | #1
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 mbox

Patch

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