summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--THANKS1
-rw-r--r--src/lalr.c16
-rw-r--r--tests/sets.at43
3 files changed, 58 insertions, 2 deletions
diff --git a/THANKS b/THANKS
index 6ddfe694..3a8baf3f 100644
--- a/THANKS
+++ b/THANKS
@@ -176,6 +176,7 @@ Tommy Nordgren tommy.nordgren@chello.se
Troy A. Johnson troyj@ecn.purdue.edu
Tys Lefering gccbison@gmail.com
Valentin Tolmer nitnelave1@gmail.com
+wcventure wcventure@126.com
Victor Khomenko victor.khomenko@newcastle.ac.uk
Victor Zverovich victor.zverovich@gmail.com
Vin Shelton acs@alumni.princeton.edu
diff --git a/src/lalr.c b/src/lalr.c
index a1f3903e..c48c726d 100644
--- a/src/lalr.c
+++ b/src/lalr.c
@@ -271,7 +271,7 @@ build_relations (void)
int nedges = 0;
for (rule **rulep = derives[var - ntokens]; *rulep; ++rulep)
{
- rule const* r = *rulep;
+ rule const *r = *rulep;
state *s = states[src];
path[0] = s->number;
@@ -295,7 +295,19 @@ build_relations (void)
for (int p = length - 2; 0 <= p && ISVAR (r->rhs[p]); --p)
{
symbol_number sym = item_number_as_symbol_number (r->rhs[p]);
- edge[nedges++] = map_goto (path[p], sym);
+ goto_number g = map_goto (path[p], sym);
+ /* Insert G if not already in EDGE.
+ FIXME: linear search. A bitset instead? */
+ {
+ bool found = false;
+ for (int j = 0; !found && j < nedges; ++j)
+ found = edge[j] == g;
+ if (!found)
+ {
+ assert (nedges < ngotos + 1);
+ edge[nedges++] = map_goto (path[p], sym);
+ }
+ }
if (!nullable[sym - ntokens])
break;
}
diff --git a/tests/sets.at b/tests/sets.at
index 3ad1a855..60c32767 100644
--- a/tests/sets.at
+++ b/tests/sets.at
@@ -304,6 +304,49 @@ AT_CLEANUP
## ----------------- ##
+## Build relations. ##
+## ----------------- ##
+
+AT_SETUP([Build relations])
+
+# The "includes" relation [DeRemer 1982] is between gotos, so of
+# course, for a given goto, there cannot be more that ngotos (number
+# of gotos) images. But we manipulate the set of images of a goto as
+# a list, without checking that an image was not already introduced.
+# So we can "register" way more images than ngotos, leading to a crash
+# (heap buffer overflow).
+#
+# http://lists.gnu.org/archive/html/bug-bison/2019-03/msg00007.html
+
+AT_DATA([input.y],
+[[%%
+expr: term | term | term | term | term | term
+term: 'n'
+]])
+
+AT_BISON_CHECK([[-fcaret input.y]], [], [],
+[[input.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
+input.y:2.14-17: warning: rule useless in parser due to conflicts [-Wother]
+ expr: term | term | term | term | term | term
+ ^~~~
+input.y:2.21-24: warning: rule useless in parser due to conflicts [-Wother]
+ expr: term | term | term | term | term | term
+ ^~~~
+input.y:2.28-31: warning: rule useless in parser due to conflicts [-Wother]
+ expr: term | term | term | term | term | term
+ ^~~~
+input.y:2.35-38: warning: rule useless in parser due to conflicts [-Wother]
+ expr: term | term | term | term | term | term
+ ^~~~
+input.y:2.42-45: warning: rule useless in parser due to conflicts [-Wother]
+ expr: term | term | term | term | term | term
+ ^~~~
+]])
+
+AT_CLEANUP
+
+
+## ----------------- ##
## Reduced Grammar. ##
## ----------------- ##