This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix segfault in try_forward_edges


Hi!

The following testcase segfaults the compiler on IA-32 with -O+.
The problem is that if 2 b successor edges are successfully
forwarded, threaded_edges[0] still contains threaded edge from the first
loop.
So when the function later does:
		  n = 0;
...
                  if (n >= nthreaded_edges)
                    abort ();
                  t = threaded_edges [n++];
it will walk through edge from the first loop and not from the second as it
expects.
Fixed below, bootstrap succeeded on i386-redhat-linux, regression testing
pending. Ok to commit?

2002-01-09  Jakub Jelinek  <jakub@redhat.com>

	* cfgcleanup.c (try_forward_edges): Reset nthreaded_edges for
	each B successor attempted.

	* gcc.c-torture/compile/20020109-1.c: New test.

--- gcc/testsuite/gcc.c-torture/compile/20020109-1.c.jj	Wed Jan  9 16:51:36 2002
+++ gcc/testsuite/gcc.c-torture/compile/20020109-1.c	Wed Jan  9 16:52:53 2002
@@ -0,0 +1,23 @@
+/* This testcase ICEd when 2 different successors of a basic block
+   were successfully threaded and try_forward_edges was not expecting
+   that.  */
+
+typedef struct A
+{
+  struct A *s, *t;
+  unsigned int u;
+} A;
+
+void bar (A *);
+
+void
+foo (A *x, A *y, A *z)
+{
+  while (y
+	 && (((y && y->t && y->t->u) ? y : z)->t
+	     == ((x && x->t && x->t->u) ? x : z)->t))
+    y = y->s;
+
+  if (y)
+    bar (y);
+}
--- gcc/cfgcleanup.c.jj	Mon Jan  7 14:57:23 2002
+++ gcc/cfgcleanup.c	Wed Jan  9 16:47:49 2002
@@ -370,7 +370,7 @@ try_forward_edges (mode, b)
 {
   bool changed = false;
   edge e, next, *threaded_edges = NULL;
-  int nthreaded_edges = 0;
+  int nthreaded_edges;
 
   for (e = b->succ; e; e = next)
     {
@@ -390,6 +390,7 @@ try_forward_edges (mode, b)
 
       target = first = e->dest;
       counter = 0;
+      nthreaded_edges = 0;
 
       while (counter < n_basic_blocks)
 	{
@@ -412,7 +413,7 @@ try_forward_edges (mode, b)
 	      edge t = thread_jump (mode, e, target);
 	      if (t)
 		{
-		  if (!nthreaded_edges)
+		  if (threaded_edges == NULL)
 		    threaded_edges = xmalloc (sizeof (*threaded_edges)
 					      * n_basic_blocks);
 		  else

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]