diff mbox

Fix ICE with missing lhs on noreturn call with addressable return type (PR tree-optimization/79267)

Message ID 20170130181007.GJ13290@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Jan. 30, 2017, 6:10 p.m. UTC
Hi!

This is yet another occurrence of the bug that we drop lhs on noreturn
calls even when it actually should not be dropped (if it has addressable
type or if it is a variable length type).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-01-30  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/79267
	* value-prof.c (gimple_ic): Only drop lhs for noreturn calls
	if should_remove_lhs_p is true.

	* g++.dg/opt/pr79267.C: New test.


	Jakub

Comments

Richard Biener Jan. 31, 2017, 6:37 a.m. UTC | #1
On January 30, 2017 7:10:07 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>This is yet another occurrence of the bug that we drop lhs on noreturn
>calls even when it actually should not be dropped (if it has
>addressable
>type or if it is a variable length type).
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-01-30  Jakub Jelinek  <jakub@redhat.com>
>
>	PR tree-optimization/79267
>	* value-prof.c (gimple_ic): Only drop lhs for noreturn calls
>	if should_remove_lhs_p is true.
>
>	* g++.dg/opt/pr79267.C: New test.
>
>--- gcc/value-prof.c.jj	2017-01-01 12:45:38.000000000 +0100
>+++ gcc/value-prof.c	2017-01-30 12:30:47.179820533 +0100
>@@ -1358,7 +1358,8 @@ gimple_ic (gcall *icall_stmt, struct cgr
>   dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt));
>   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
>   dflags = flags_from_decl_or_type (direct_call->decl);
>-  if ((dflags & ECF_NORETURN) != 0)
>+  if ((dflags & ECF_NORETURN) != 0
>+      && should_remove_lhs_p (gimple_call_lhs (dcall_stmt)))
>     gimple_call_set_lhs (dcall_stmt, NULL_TREE);
>   gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
> 
>--- gcc/testsuite/g++.dg/opt/pr79267.C.jj	2017-01-30 12:36:07.605516857
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr79267.C	2017-01-30 12:35:51.000000000
>+0100
>@@ -0,0 +1,69 @@
>+// PR tree-optimization/79267
>+// { dg-do compile }
>+// { dg-options "-O3" }
>+
>+struct A { A (int); };
>+struct B
>+{
>+  virtual void av () = 0;
>+  void aw ();
>+  void h () { av (); aw (); }
>+};
>+template <class T> struct G : B
>+{
>+  T ba;
>+  G (int, T) : ba (0) {}
>+  void av () { ba (0); }
>+};
>+struct I
>+{
>+  B *bc;
>+  template <class j, class T> I (j, T) try { G<T> (0, 0); } catch
>(...) {}
>+  ~I () { bc->h (); }
>+};
>+template <class M> struct C { typedef M *i; };
>+template <class M> struct J
>+{
>+  J ();
>+  template <class O, class T> J (O, T p2) : be (0, p2) {}
>+  typename C<M>::i operator-> ();
>+  I be;
>+};
>+struct H : A { H () : A (0) {} };
>+struct D { J<int> d; void q (); };
>+template <typename = int> class bs;
>+int z;
>+
>+void
>+foo (int p1, int *, int)
>+{
>+  if (p1 == 0)
>+    throw H ();
>+}
>+
>+D bar ();
>+template <typename T> struct L
>+{
>+  struct K { K (int); void operator() (int *) { bar ().q (); } };
>+  static J<T> bp () { bq (0); }
>+  template <typename br> static void bq (br) { J<T> (0, K (0)); }
>+};
>+struct F
>+{
>+  virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ());
>}
>+};
>+
>+void
>+baz ()
>+{
>+  if (z)
>+    {
>+      J<F> d, e;
>+      d->x (0);
>+      e->x (0);
>+    }
>+  J<F> v, i, j;
>+  v->x (0);
>+  i->x (0);
>+  j->x (0);
>+}
>
>	Jakub
diff mbox

Patch

--- gcc/value-prof.c.jj	2017-01-01 12:45:38.000000000 +0100
+++ gcc/value-prof.c	2017-01-30 12:30:47.179820533 +0100
@@ -1358,7 +1358,8 @@  gimple_ic (gcall *icall_stmt, struct cgr
   dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt));
   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
   dflags = flags_from_decl_or_type (direct_call->decl);
-  if ((dflags & ECF_NORETURN) != 0)
+  if ((dflags & ECF_NORETURN) != 0
+      && should_remove_lhs_p (gimple_call_lhs (dcall_stmt)))
     gimple_call_set_lhs (dcall_stmt, NULL_TREE);
   gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
 
--- gcc/testsuite/g++.dg/opt/pr79267.C.jj	2017-01-30 12:36:07.605516857 +0100
+++ gcc/testsuite/g++.dg/opt/pr79267.C	2017-01-30 12:35:51.000000000 +0100
@@ -0,0 +1,69 @@ 
+// PR tree-optimization/79267
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct A { A (int); };
+struct B
+{
+  virtual void av () = 0;
+  void aw ();
+  void h () { av (); aw (); }
+};
+template <class T> struct G : B
+{
+  T ba;
+  G (int, T) : ba (0) {}
+  void av () { ba (0); }
+};
+struct I
+{
+  B *bc;
+  template <class j, class T> I (j, T) try { G<T> (0, 0); } catch (...) {}
+  ~I () { bc->h (); }
+};
+template <class M> struct C { typedef M *i; };
+template <class M> struct J
+{
+  J ();
+  template <class O, class T> J (O, T p2) : be (0, p2) {}
+  typename C<M>::i operator-> ();
+  I be;
+};
+struct H : A { H () : A (0) {} };
+struct D { J<int> d; void q (); };
+template <typename = int> class bs;
+int z;
+
+void
+foo (int p1, int *, int)
+{
+  if (p1 == 0)
+    throw H ();
+}
+
+D bar ();
+template <typename T> struct L
+{
+  struct K { K (int); void operator() (int *) { bar ().q (); } };
+  static J<T> bp () { bq (0); }
+  template <typename br> static void bq (br) { J<T> (0, K (0)); }
+};
+struct F
+{
+  virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ()); }
+};
+
+void
+baz ()
+{
+  if (z)
+    {
+      J<F> d, e;
+      d->x (0);
+      e->x (0);
+    }
+  J<F> v, i, j;
+  v->x (0);
+  i->x (0);
+  j->x (0);
+}