summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-06-26 07:33:51 +0200
committerAkim Demaille <akim.demaille@gmail.com>2020-06-27 08:16:07 +0200
commitcf6d8d0631d6d4c82a00843b1fe3d6b13e7ff436 (patch)
treef1c7f3d235f85d1ee15bef997dfb7bc692672620
parent8f44164443e8cc04f7931cd5fdb39a0cc48b39a4 (diff)
downloadbison-cf6d8d0631d6d4c82a00843b1fe3d6b13e7ff436.tar.gz
ielr: fix crash on memory management
Reported by Dwight Guth. https://lists.gnu.org/r/bug-bison/2020-06/msg00037.html * src/AnnotationList.c (AnnotationList__computePredecessorAnnotations): Beware that SBITSET__FOR_EACH nests _two_ for-loops, so "break" does not actually break out of it. That was the only occurrence in the code. * src/Sbitset.h (SBITSET__FOR_EACH): Warn passersby.
-rw-r--r--NEWS4
-rw-r--r--THANKS1
-rw-r--r--src/AnnotationList.c4
-rw-r--r--src/Sbitset.h2
4 files changed, 10 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 6feb8258..d9da8192 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,10 @@ GNU Bison NEWS
string aliases semantically equivalent but syntactically different (e.g.,
"A", "\x41", "\101") are considered to be different.
+*** Crash when generating IELR
+
+ An old, well hidden, bug in the generation of IELR parsers was fixed.
+
** New features
*** File prefix mapping
diff --git a/THANKS b/THANKS
index 36df5e29..af24ceaa 100644
--- a/THANKS
+++ b/THANKS
@@ -59,6 +59,7 @@ Di-an Jan dianj@freeshell.org
Dick Streefland dick.streefland@altium.nl
Didier Godefroy dg@ulysium.net
Don Macpherson donmac703@gmail.com
+Dwight Guth dwight.guth@runtimeverification.com
Efi Fogel efifogel@gmail.com
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de
Eric Blake ebb9@byu.net
diff --git a/src/AnnotationList.c b/src/AnnotationList.c
index a95a67be..421643b2 100644
--- a/src/AnnotationList.c
+++ b/src/AnnotationList.c
@@ -276,7 +276,8 @@ AnnotationList__computePredecessorAnnotations (
obstack_free (annotations_obstackp,
annotation_node->contributions[ci]);
annotation_node->contributions[ci] = NULL;
- break;
+ // "Break" out of SBITSET__FOR_EACH.
+ goto after_sbitset__for_each;
}
else
{
@@ -309,6 +310,7 @@ AnnotationList__computePredecessorAnnotations (
predecessor_item);
}
}
+ after_sbitset__for_each:;
}
if (annotation_node->contributions[ci])
{
diff --git a/src/Sbitset.h b/src/Sbitset.h
index 997dab2f..c54def4e 100644
--- a/src/Sbitset.h
+++ b/src/Sbitset.h
@@ -81,6 +81,8 @@ void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
*ptr_self = *ptr_other1 | *ptr_other2; \
} while (0)
+/* ATTENTION: there are *two* loops here, "break" and "continue" will
+ not apply to the whole loop, just the inner one. */
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
if (*(ITER) != 0) \