re PR c++/79267 (internal compiler error with -O3 or -O2 -finline-functions)
authorJakub Jelinek <jakub@redhat.com>
Tue, 31 Jan 2017 08:33:36 +0000 (09:33 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 31 Jan 2017 08:33:36 +0000 (09:33 +0100)
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.

From-SVN: r245053

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr79267.C [new file with mode: 0644]
gcc/value-prof.c

index eed607a8d1fcd748243032232e619b16b713b725..8916373f8260ce9e0ccce4cdec27e1ceaa9714b9 100644 (file)
@@ -1,3 +1,9 @@
+2017-01-31  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.
+
 2017-01-30  Alexandre Oliva <aoliva@redhat.com>
 
        PR debug/63238
index 8210eae17ba688bfbd4b88c7c878486eb6dafe47..96b25d63061f0edd5f42aa7d1480d2827fa91260 100644 (file)
@@ -1,3 +1,8 @@
+2017-01-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/79267
+       * g++.dg/opt/pr79267.C: New test.
+
 2017-01-30  Alexandre Oliva <aoliva@redhat.com>
 
        PR debug/63238
diff --git a/gcc/testsuite/g++.dg/opt/pr79267.C b/gcc/testsuite/g++.dg/opt/pr79267.C
new file mode 100644 (file)
index 0000000..177eee6
--- /dev/null
@@ -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);
+}
index d4da8c45a221d47e0a837dccde17b1dbf24a8376..097e4094095b1bf9c328b2af976206b28f44180e 100644 (file)
@@ -1358,7 +1358,8 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
   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);