diff mbox

[PR,tree-optimization/70190] Handle computed goto with constant address in jump threader

Message ID 56E34762.9060907@redhat.com
State New
Headers show

Commit Message

Jeff Law March 11, 2016, 10:32 p.m. UTC
This is arguably invalid code, but we certainly shouldn't be faulting in 
these kind of situations.

The FSM threader was presented with a computed goto.  It was able to 
trace values backwards through a PHI to a constant (as in a constant 
integer, not a label).

In that case find_taken_edge will return NULL and we need to gracefully 
handle it.

Bootstrapped and regression tested on x86_64-linux-gnu.  Installing on 
the trunk momentarily.

Jeff
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3a7351..1bc7ab5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@ 
 2016-03-11  Jeff Law  <law@redhat.com>
 
+	PR tree-optimization/70190
+	* tree-ssa-threadbackward.c (fsm_find_control_statement_thread_paths):
+	Handle cases where we can not extract the taken edge, even though we
+	found a constant value.
+
 	PR tree-optimization/64058
 	* tree-ssa-coalesce.c (struct coalesce_pair): Add new field INDEX.
 	(num_coalesce_pairs): Move up earlier in file.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f42e943..e48430c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2016-03-11  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/70190
+	* gcc.c-torture/compile/pr70190.c: New test.
+
 2016-03-11  David Malcolm  <dmalcolm@redhat.com>
 
 	PR c/68187
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70190.c b/gcc/testsuite/gcc.c-torture/compile/pr70190.c
new file mode 100644
index 0000000..d3d209a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr70190.c
@@ -0,0 +1,14 @@ 
+/* { dg-require-effective-target indirect_jumps } */
+/* { dg-require-effective-target label_values } */
+
+
+int
+fn1 ()
+{
+  static char a[] = "foo";
+  static void *b[] = { &&l1, &&l2 };
+  goto *(b[1]);
+ l1: goto *(a[0]);
+ l2: return 0;
+}
+
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 6f1b757..88f8d5e 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -385,6 +385,16 @@  fsm_find_control_statement_thread_paths (tree name,
 
 	     We have to know the outgoing edge to figure this out.  */
 	  edge taken_edge = find_taken_edge ((*path)[0], arg);
+
+	  /* There are cases where we may not be able to extract the
+	     taken edge.  For example, a computed goto to an absolute
+	     address.  Handle those cases gracefully.  */
+	  if (taken_edge == NULL)
+	    {
+	      path->pop ();
+	      continue;
+	    }
+
 	  bool creates_irreducible_loop = false;
 	  if (threaded_through_latch
 	      && loop == taken_edge->dest->loop_father