Hi!

On Wed, 7 Dec 2016 18:28:39 +0100, Jakub Jelinek <ja...@redhat.com> wrote:
> 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.

One year later, as discussed in <https://gcc.gnu.org/PR83301>, backported
to gcc-6-branch in r255538:

commit 57354e3c971f9a17f11a3fd28342eaea50ea0fd3
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Mon Dec 11 09:49:25 2017 +0000

    [PR c++/83301] cgraph.c segfault
    
    Backport trunk r243377:
    
        gcc/
        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.
    
        gcc/testsuite/
        2016-12-07  Jakub Jelinek  <ja...@redhat.com>
    
        PR c++/78692
        * g++.dg/torture/pr78692.C: New test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@255538 
138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                          |   12 ++++++++++++
 gcc/cgraph.c                           |    2 +-
 gcc/testsuite/ChangeLog                |   10 ++++++++++
 gcc/testsuite/g++.dg/torture/pr78692.C |   26 ++++++++++++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index e586870..35a70d4 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,3 +1,15 @@
+2017-12-11  Thomas Schwinge  <tho...@codesourcery.com>
+
+       PR c++/83301
+
+       Backport trunk r243377:
+       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.
+
 2017-12-04  Sebastian Peryt  <sebastian.pe...@intel.com>
        H.J. Lu  <hongjiu...@intel.com>
 
diff --git gcc/cgraph.c gcc/cgraph.c
index 6ff8f26..0c9d969 100644
--- gcc/cgraph.c
+++ gcc/cgraph.c
@@ -1259,7 +1259,6 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
   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;
@@ -1529,6 +1528,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
     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_flags (new_stmt) & ECF_NORETURN)
       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
diff --git gcc/testsuite/ChangeLog gcc/testsuite/ChangeLog
index 6a1b459..0fae4dc 100644
--- gcc/testsuite/ChangeLog
+++ gcc/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2017-12-11  Thomas Schwinge  <tho...@codesourcery.com>
+
+       PR c++/83301
+
+       Backport trunk r243377:
+       2016-12-07  Jakub Jelinek  <ja...@redhat.com>
+
+       PR c++/78692
+       * g++.dg/torture/pr78692.C: New test.
+
 2017-12-04  Sebastian Peryt  <sebastian.pe...@intel.com>
        H.J. Lu  <hongjiu...@intel.com>
 
diff --git gcc/testsuite/g++.dg/torture/pr78692.C 
gcc/testsuite/g++.dg/torture/pr78692.C
new file mode 100644
index 0000000..57a0d2f
--- /dev/null
+++ gcc/testsuite/g++.dg/torture/pr78692.C
@@ -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);
+}
+}


Grüße
 Thomas

Reply via email to