]> git.saurik.com Git - bison.git/commitdiff
Bison dumps core on bash.y.
authorAkim Demaille <akim@epita.fr>
Mon, 10 Dec 2001 08:43:38 +0000 (08:43 +0000)
committerAkim Demaille <akim@epita.fr>
Mon, 10 Dec 2001 08:43:38 +0000 (08:43 +0000)
Reported by Pascal Bart.
* src/warshall.c (bitmatrix_print): New.
(TC): Use it.
When performing a transitive closure R(i, j) && R(j, k) => R(i, k),
j must be the outer loop.
* tests/regression.at (Broken Closure): New.

ChangeLog
src/lalr.c
src/warshall.c
tests/regression.at

index 419a36d4d4f3d8f4405d543e975955a88c193ea1..4240599dd02f3d45a18f3e969885e5b77de16ce7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2001-12-10  Akim Demaille  <akim@epita.fr>
+
+       Bison dumps core on bash.y.
+       Reported by Pascal Bart.
+
+       * src/warshall.c (bitmatrix_print): New.
+       (TC): Use it.
+       When performing a transitive closure R(i, j) && R(j, k) => R(i, k),
+       j must be the outer loop.
+       * tests/regression.at (Broken Closure): New.
+
 2001-12-05  Akim Demaille  <akim@epita.fr>
 
        Version 1.30f.
 2001-12-05  Akim Demaille  <akim@epita.fr>
 
        Version 1.30f.
index 09dc7602892ba4e37fba7010a3e7050086d5f3ac..44eaa3edb55e1f116536102b15932f9def6ea203 100644 (file)
@@ -247,16 +247,17 @@ set_goto_map (void)
 
   ngotos = 0;
   for (sp = first_shift; sp; sp = sp->next)
 
   ngotos = 0;
   for (sp = first_shift; sp; sp = sp->next)
-    for (i = sp->nshifts - 1; i >= 0 && SHIFT_IS_GOTO (sp, i); --i)
-      {
-       symbol = state_table[sp->shifts[i]].accessing_symbol;
+    if (sp->nshifts)
+      for (i = sp->nshifts - 1; i >= 0 && SHIFT_IS_GOTO (sp, i); --i)
+       {
+         symbol = state_table[sp->shifts[i]].accessing_symbol;
 
 
-       if (ngotos == MAXSHORT)
-         fatal (_("too many gotos (max %d)"), MAXSHORT);
+         if (ngotos == MAXSHORT)
+           fatal (_("too many gotos (max %d)"), MAXSHORT);
 
 
-       ngotos++;
-       goto_map[symbol]++;
-      }
+         ngotos++;
+         goto_map[symbol]++;
+       }
 
   k = 0;
   for (i = ntokens; i < nsyms; i++)
 
   k = 0;
   for (i = ntokens; i < nsyms; i++)
@@ -277,15 +278,16 @@ set_goto_map (void)
   for (sp = first_shift; sp; sp = sp->next)
     {
       state1 = sp->number;
   for (sp = first_shift; sp; sp = sp->next)
     {
       state1 = sp->number;
-      for (i = sp->nshifts - 1; i >= 0 && SHIFT_IS_GOTO (sp, i); --i)
-       {
-         state2 = sp->shifts[i];
-         symbol = state_table[state2].accessing_symbol;
-
-         k = temp_map[symbol]++;
-         from_state[k] = state1;
-         to_state[k] = state2;
-       }
+      if (sp->nshifts)
+       for (i = sp->nshifts - 1; i >= 0 && SHIFT_IS_GOTO (sp, i); --i)
+         {
+           state2 = sp->shifts[i];
+           symbol = state_table[state2].accessing_symbol;
+
+           k = temp_map[symbol]++;
+           from_state[k] = state1;
+           to_state[k] = state2;
+         }
     }
 
   XFREE (temp_map + ntokens);
     }
 
   XFREE (temp_map + ntokens);
index a9d579e663048ca9add44a52b7ae6af072eb5d39..5963f472ddeef71da9203e2880f1b63966e4244f 100644 (file)
@@ -20,6 +20,7 @@
 
 
 #include "system.h"
 
 
 #include "system.h"
+#include "getargs.h"
 #include "warshall.h"
 
 /*-------------------------------------------------------------.
 #include "warshall.h"
 
 /*-------------------------------------------------------------.
 | transive closure of what was given.                          |
 `-------------------------------------------------------------*/
 
 | transive closure of what was given.                          |
 `-------------------------------------------------------------*/
 
+static void
+bitmatrix_print (const char *title, unsigned *matrix, size_t size)
+{
+  size_t i, j;
+  size_t rowsize = WORDSIZE (size) * sizeof (unsigned);
+#define ROW(Num) ((unsigned *) ((char *) matrix + ((Num) * rowsize)))
+
+  /* Title. */
+  fprintf (stderr, "%s BEGIN\n", title);
+
+  /* Column numbers. */
+  fputs ("   ", stderr);
+  for (i = 0; i < size; ++i)
+    putc (i / 10 ? '0' + i / 10 : ' ', stderr);
+  putc ('\n', stderr);
+  fputs ("   ", stderr);
+  for (i = 0; i < size; ++i)
+    fprintf (stderr, "%d", i % 10);
+  putc ('\n', stderr);
+
+  /* Bar. */
+  fputs ("  +", stderr);
+  for (i = 0; i < size; ++i)
+    putc ('-', stderr);
+  fputs ("+\n", stderr);
+
+  /* Contents. */
+  for (i = 0; i < size; ++i)
+    {
+      fprintf (stderr, "%2d|", i);
+      for (j = 0; j < size; ++j)
+       fputs (BITISSET (ROW (i), j) ? "1" : " ", stderr);
+      fputs ("|\n", stderr);
+    }
+
+  /* Bar. */
+  fputs ("  +", stderr);
+  for (i = 0; i < size; ++i)
+    putc ('-', stderr);
+  fputs ("+\n", stderr);
+
+  /* End title. */
+  fprintf (stderr, "%s END\n\n", title);
+}
+
 #define R(Num) (unsigned *) ((char *) R + ((Num) * rowsize))
 
 static void
 #define R(Num) (unsigned *) ((char *) R + ((Num) * rowsize))
 
 static void
@@ -35,12 +81,21 @@ TC (unsigned *R, int n)
   int rowsize = WORDSIZE (n) * sizeof (unsigned);
   int i, j, k;
 
   int rowsize = WORDSIZE (n) * sizeof (unsigned);
   int i, j, k;
 
+  if (trace_flag)
+    bitmatrix_print ("TC: Input", R, n);
+
+  /* R (J, I) && R (I, K) => R (J, K).
+     I *must* be the outter loop. */
+
   for (i = 0; i < n; ++i)
     for (j = 0; j < n; ++j)
   for (i = 0; i < n; ++i)
     for (j = 0; j < n; ++j)
-      if (BITISSET (R (i), j))
-       for (k = 0; k < rowsize; ++k)
+      if (BITISSET (R (j), i))
+       for (k = 0; k < n; ++k)
          if (BITISSET (R (i), k))
            SETBIT (R (j), k);
          if (BITISSET (R (i), k))
            SETBIT (R (j), k);
+
+  if (trace_flag)
+    bitmatrix_print ("TC: Output", R, n);
 }
 
 
 }
 
 
index f141c4b852bfbd76c91ddec1e37a2df3ccbdd203..70e3420bf08ea4b2e40c93b9afa3511e161c8e4d 100644 (file)
@@ -611,3 +611,78 @@ AT_CLEANUP
 
 AT_TEST_CPP_GUARD_H([input/input])
 AT_TEST_CPP_GUARD_H([9foo])
 
 AT_TEST_CPP_GUARD_H([input/input])
 AT_TEST_CPP_GUARD_H([9foo])
+
+
+## ---------------- ##
+## Broken Closure.  ##
+## ---------------- ##
+
+# TC was once broken during a massive `simplification' of the code.
+# It resulted in bison dumping core on the following grammar (the
+# computation of FIRSTS uses TC).  It managed to produce a pretty
+# exotic closure:
+#
+# TC: Input
+#
+#    01234567
+#   +--------+
+#  0| 1      |
+#  1|  1     |
+#  2|   1    |
+#  3|    1   |
+#  4|     1  |
+#  5|      1 |
+#  6|       1|
+#  7|        |
+#   +--------+
+#
+# TC: Output
+#
+#    01234567
+#   +--------+
+#  0| 1      |
+#  1| 111    |
+#  2| 111    |
+#  3| 1111   |
+#  4| 111 1  |
+#  5| 111  1 |
+#  6| 111   1|
+#  7| 111    |
+#   +--------+
+#
+# instead of that below.
+
+AT_SETUP([Broken Closure])
+
+AT_DATA([input.y],
+[[%%
+a: b
+b: c
+c: d
+d: e
+e: f
+f: g
+g: h
+h: 'h'
+]])
+
+AT_CHECK([bison --trace input.y 2>&1 |
+          sed -n '/^TC: Output BEGIN/,/^TC: Output END/p'],
+         [0],
+[[TC: Output BEGIN
+           @&t@
+   01234567
+  +--------+
+ 0| 1111111|
+ 1|  111111|
+ 2|   11111|
+ 3|    1111|
+ 4|     111|
+ 5|      11|
+ 6|       1|
+ 7|        |
+  +--------+
+TC: Output END
+]])
+
+AT_CLEANUP