Hi!

The code in this function assumes that lhs is the lhs of new_stmt (it tests
that new_stmt is a noreturn call etc.), but that is only the case if
new_stmt == e->call_stmt.  But in the function it can be set to various
other stmts.  Nothing tests the lhs before this noreturn handling, so this
patch fixes it by moving the initialization of lhs right before the use.

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

2016-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/78692
        * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Set lhs
        var to lhs of new_stmt right before noreturn handling rather than to
        lhs of e->call_stmt early.

        * g++.dg/torture/pr78692.C: New test.

--- gcc/cgraph.c.jj     2016-11-30 13:57:11.000000000 +0100
+++ gcc/cgraph.c        2016-12-06 09:51:32.513140728 +0100
@@ -1271,7 +1271,6 @@ cgraph_edge::redirect_call_stmt_to_calle
   cgraph_edge *e = this;
 
   tree decl = gimple_call_fndecl (e->call_stmt);
-  tree lhs = gimple_call_lhs (e->call_stmt);
   gcall *new_stmt;
   gimple_stmt_iterator gsi;
   bool skip_bounds = false;
@@ -1526,6 +1525,7 @@ cgraph_edge::redirect_call_stmt_to_calle
     gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
 
   /* If the call becomes noreturn, remove the LHS if possible.  */
+  tree lhs = gimple_call_lhs (new_stmt);
   if (lhs
       && gimple_call_noreturn_p (new_stmt)
       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
--- gcc/testsuite/g++.dg/torture/pr78692.C.jj   2016-12-06 09:55:39.295999164 
+0100
+++ gcc/testsuite/g++.dg/torture/pr78692.C      2016-12-06 09:55:25.000000000 
+0100
@@ -0,0 +1,26 @@
+// PR c++/78692
+
+int a;
+void *b;
+extern "C" {
+struct C {
+  virtual int d ();
+};
+struct E {
+  virtual int operator () (int, const void *, int) = 0;
+};
+class F {
+  int g ();
+  int h;
+  E &i;
+};
+struct : C, E {
+  int operator () (int, const void *, int) { throw int(); }
+} j;
+
+int
+F::g ()
+{
+  a = i (h, b, 0);
+}
+}

        Jakub

Reply via email to