re PR sanitizer/81262 (verify_flow_info failed for asmgoto test-case with -fsanitize...
authorJakub Jelinek <jakub@redhat.com>
Sat, 1 Jul 2017 08:16:27 +0000 (10:16 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 1 Jul 2017 08:16:27 +0000 (10:16 +0200)
PR sanitizer/81262
* bb-reorder.c (fix_up_fall_thru_edges): Move variable declarations to
the right scopes, make sure cond_jump isn't preserved between multiple
iterations.  Search for fallthru edge whenever there are 3+ edges and
use find_fallthru_edge for it.

* gcc.c-torture/compile/pr81262.c: New test.
* g++.dg/ubsan/pr81262.C: New test.

From-SVN: r249865

gcc/ChangeLog
gcc/bb-reorder.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr81262.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr81262.c [new file with mode: 0644]

index ce144a0..dd8e1d2 100644 (file)
@@ -1,3 +1,11 @@
+2017-07-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81262
+       * bb-reorder.c (fix_up_fall_thru_edges): Move variable declarations to
+       the right scopes, make sure cond_jump isn't preserved between multiple
+       iterations.  Search for fallthru edge whenever there are 3+ edges and
+       use find_fallthru_edge for it.
+
 2017-06-29  Jan Hubicka  <hubicka@ucw.cz>
 
        Patch by Alexander Monakov <amonakov@ispras.ru>
index 276ab58..846c291 100644 (file)
@@ -1812,18 +1812,15 @@ static void
 fix_up_fall_thru_edges (void)
 {
   basic_block cur_bb;
-  basic_block new_bb;
-  edge succ1;
-  edge succ2;
-  edge fall_thru;
-  edge cond_jump = NULL;
-  bool cond_jump_crosses;
-  int invert_worked;
-  rtx_insn *old_jump;
-  rtx_code_label *fall_thru_label;
 
   FOR_EACH_BB_FN (cur_bb, cfun)
     {
+      edge succ1;
+      edge succ2;
+      edge fall_thru = NULL;
+      edge cond_jump = NULL;
+      rtx_code_label *fall_thru_label;
+
       fall_thru = NULL;
       if (EDGE_COUNT (cur_bb->succs) > 0)
        succ1 = EDGE_SUCC (cur_bb, 0);
@@ -1849,20 +1846,8 @@ fix_up_fall_thru_edges (void)
          fall_thru = succ2;
          cond_jump = succ1;
        }
-      else if (succ1
-              && (block_ends_with_call_p (cur_bb)
-                  || can_throw_internal (BB_END (cur_bb))))
-       {
-         edge e;
-         edge_iterator ei;
-
-         FOR_EACH_EDGE (e, ei, cur_bb->succs)
-           if (e->flags & EDGE_FALLTHRU)
-             {
-               fall_thru = e;
-               break;
-             }
-       }
+      else if (succ2 && EDGE_COUNT (cur_bb->succs) > 2)
+       fall_thru = find_fallthru_edge (cur_bb->succs);
 
       if (fall_thru && (fall_thru->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)))
        {
@@ -1873,9 +1858,9 @@ fix_up_fall_thru_edges (void)
              /* The fall_thru edge crosses; now check the cond jump edge, if
                 it exists.  */
 
-             cond_jump_crosses = true;
-             invert_worked  = 0;
-             old_jump = BB_END (cur_bb);
+             bool cond_jump_crosses = true;
+             int invert_worked = 0;
+             rtx_insn *old_jump = BB_END (cur_bb);
 
              /* Find the jump instruction, if there is one.  */
 
@@ -1895,12 +1880,13 @@ fix_up_fall_thru_edges (void)
                      /* Find label in fall_thru block. We've already added
                         any missing labels, so there must be one.  */
 
-                     fall_thru_label = block_label (fall_thru->dest);
+                     rtx_code_label *fall_thru_label
+                       = block_label (fall_thru->dest);
 
                      if (old_jump && fall_thru_label)
                        {
-                         rtx_jump_insn *old_jump_insn =
-                               dyn_cast <rtx_jump_insn *> (old_jump);
+                         rtx_jump_insn *old_jump_insn
+                           = dyn_cast <rtx_jump_insn *> (old_jump);
                          if (old_jump_insn)
                            invert_worked = invert_jump (old_jump_insn,
                                                         fall_thru_label, 0);
@@ -1931,7 +1917,7 @@ fix_up_fall_thru_edges (void)
                     becomes EDGE_CROSSING.  */
 
                  fall_thru->flags &= ~EDGE_CROSSING;
-                 new_bb = force_nonfallthru (fall_thru);
+                 basic_block new_bb = force_nonfallthru (fall_thru);
 
                  if (new_bb)
                    {
index 73ef3a0..c71540a 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81262
+       * gcc.c-torture/compile/pr81262.c: New test.
+       * g++.dg/ubsan/pr81262.C: New test.
+
 2017-06-29  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/81261
diff --git a/gcc/testsuite/g++.dg/ubsan/pr81262.C b/gcc/testsuite/g++.dg/ubsan/pr81262.C
new file mode 100644 (file)
index 0000000..1b360de
--- /dev/null
@@ -0,0 +1,14 @@
+// PR sanitizer/81262
+// { dg-do compile }
+// { dg-options "-O2 -fsanitize=unreachable" }
+
+int
+foo ()
+{
+  asm goto ("" : : : : l1, l2);
+  __builtin_unreachable ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr81262.c b/gcc/testsuite/gcc.c-torture/compile/pr81262.c
new file mode 100644 (file)
index 0000000..68fbea2
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR sanitizer/81262 */
+
+void bar (void) __attribute__((cold, noreturn));
+
+int
+foo (void)
+{
+  asm goto ("" : : : : l1, l2);
+  bar ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}