re PR ipa/68470 (Internal Compiler Error observed by g++-4.9.2 and a few other versio...
authorRichard Biener <rguenther@suse.de>
Tue, 1 Dec 2015 11:35:21 +0000 (11:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 1 Dec 2015 11:35:21 +0000 (11:35 +0000)
2015-12-01  Richard Biener  <rguenther@suse.de>

PR ipa/68470
* ipa-split.c (split_function): Handle main part not returning.

* g++.dg/torture/pr68470.C: New testcase.

From-SVN: r231108

gcc/ChangeLog
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr68470.C [new file with mode: 0644]

index 48256e9..f908fe6 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-01  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/68470
+       * ipa-split.c (split_function): Handle main part not returning.
+
 2015-12-01  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR middle-end/68595
index be33dda..56c954b 100644 (file)
@@ -1205,7 +1205,6 @@ split_function (basic_block return_bb, struct split_point *split_point,
   edge e;
   edge_iterator ei;
   tree retval = NULL, real_retval = NULL, retbnd = NULL;
-  bool split_part_return_p = false;
   bool with_bounds = chkp_function_instrumented_p (current_function_decl);
   gimple *last_stmt = NULL;
   unsigned int i;
@@ -1246,12 +1245,28 @@ split_function (basic_block return_bb, struct split_point *split_point,
        args_to_pass.safe_push (arg);
       }
 
-  /* See if the split function will return.  */
+  /* See if the split function or the main part will return.  */
+  bool main_part_return_p = false;
+  bool split_part_return_p = false;
   FOR_EACH_EDGE (e, ei, return_bb->preds)
-    if (bitmap_bit_p (split_point->split_bbs, e->src->index))
-      break;
-  if (e)
-    split_part_return_p = true;
+    {
+      if (bitmap_bit_p (split_point->split_bbs, e->src->index))
+       split_part_return_p = true;
+      else
+       main_part_return_p = true;
+    }
+  /* The main part also returns if we we split on a fallthru edge
+     and the split part returns.  */
+  if (split_part_return_p)
+    FOR_EACH_EDGE (e, ei, split_point->entry_bb->preds)
+      {
+       if (! bitmap_bit_p (split_point->split_bbs, e->src->index)
+           && single_succ_p (e->src))
+         {
+           main_part_return_p = true;
+           break;
+         }
+      }
 
   /* Add return block to what will become the split function.
      We do not return; no return block is needed.  */
@@ -1295,6 +1310,11 @@ split_function (basic_block return_bb, struct split_point *split_point,
   else
     bitmap_set_bit (split_point->split_bbs, return_bb->index);
 
+  /* If the main part doesn't return pretend the return block wasn't
+     found for all of the following.  */
+  if (! main_part_return_p)
+    return_bb = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
   /* If RETURN_BB has virtual operand PHIs, they must be removed and the
      virtual operand marked for renaming as we change the CFG in a way that
      tree-inline is not able to compensate for.
index 07a9e52..8263c1b 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-01  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/68470
+       * g++.dg/torture/pr68470.C: New testcase.
+
 2015-12-01  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR middle-end/68595
diff --git a/gcc/testsuite/g++.dg/torture/pr68470.C b/gcc/testsuite/g++.dg/torture/pr68470.C
new file mode 100644 (file)
index 0000000..5dd558d
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+
+void deallocate(void *);
+void *a;
+
+struct C {
+    virtual void m_fn1();
+};
+
+struct D {
+    C *m_fn2() {
+       if (a)
+         __builtin_abort();
+    }
+};
+D getd();
+
+struct vec_int {
+    int _M_start;
+    ~vec_int() {
+       if (_M_start)
+         deallocate(&_M_start);
+    }
+};
+vec_int *b;
+
+struct I {
+    virtual void m_fn3();
+};
+
+void I::m_fn3() {
+    if (a)
+      getd().m_fn2()->m_fn1();
+    b->~vec_int();
+}
+