On 10/2/19 11:28 PM, Akim Demaille wrote:
But I see you already pushed it, although there are things I would have liked
to discuss first. Also, we now have failures in the history of master and
maint, which I strive to avoid. And the CI is red currently.
Sorry, I'm so rusty at Bison development I did not know the current
rules. What CI is that? I don't see it mentioned in
<https://www.gnu.org/software/bison/> or in
<https://savannah.gnu.org/projects/bison/>; should it be?
Please, in the future, make smaller commits, per topic.
Yes, I'll try to split things up better.
And run the test suite with an old compiler too.
How old? Are we backward compatible to (say) GCC 3.4.3? That's the
oldest I have convenient access to, though it's on reaally slow hardware.
The Bison manual says that Bison itself needs only C99, and that
Bison-generated C parsers need only C89 (or C99 for glr) or C++98, but I
don't know how that relates to compiler (and presumably library) version
numbers.
At some point I suppose we should drop support for C89 as it is now more
trouble than it's worth. But that can wait.
I don't want to break the API for the generated locations in C++. At least we
need to talk about this with users.
Yes, that makes sense. Also, if we're going to change the API for line
and column numbers, I suggest we go to a wider type instead of stopping
at 'int'. These days, 'int' and 'unsigned' are both too narrow for some
possible applications of Bison, and the only portable-to-all-modern-C
solutions that are signed are 'intmax_t' and 'long long'. I could go
with either of those.
How can we change the API to switch from 'unsigned' to 'intmax_t' (or to
'long long') without breaking existing apps? I don't have enough C++
expertise to know how to do this in the best way.
Also, I dislike the fact that the examples in the documentation become
more complex for being more robust. I fully agree that examples should
not be too naive, but IMHO going from
if (i == length)
{
length *= 2;
symbuf = realloc (symbuf, length + 1);
}
to
if (bufsize <= i)
{
ptrdiff_t maxsize
= (PTRDIFF_MAX < SIZE_MAX
? PTRDIFF_MAX : SIZE_MAX);
if ((maxsize - 40) / 2 < bufsize)
abort ();
bufsize = 2 * bufsize + 40;
symbuf = realloc (symbuf, bufsize);
if (!symbuf)
abort ();
}
clutters the documentation.
OK, I changed it back, and put in a little note saying "this code
assumes that malloc and realloc calls always succeed" or something like
that. See the first attached patch. The second attachment fixes a lack
of clarity with the documentation of malloc elsewhere, which I noticed
with the first patch.
Old compilers choke on the current code in master, we have to stop and focus on
this first.
I can help with that if you'll give me advice about how old to worry
about (as long as it's not before GCC 3.4.3 :-).
>From e356c1ca5759e5f4336842483b550cbd6a566b5d Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 3 Oct 2019 11:15:02 -0700
Subject: [PATCH 1/2] Simplify mfcalc error handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* doc/bison.texi (Mfcalc Symbol Table, Mfcalc Lexer):
Don’t abort on memory allocation failure or integer overflow.
Instead, comment that these things aren’t checked for.
---
doc/bison.texi | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/doc/bison.texi b/doc/bison.texi
index 5545313d..a89142df 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -2662,19 +2662,21 @@ found, a pointer to that symbol is returned; otherwise zero is returned.
@comment file: mfcalc.y: 3
@example
-#include <stdlib.h> /* malloc, abort. */
+@group
+/* The mfcalc code assumes that malloc and realloc
+ always succeed, and that integer calculations
+ never overflow. Production-quality code should
+ not make these assumptions. */
+#include <stdlib.h> /* malloc, realloc. */
#include <string.h> /* strlen. */
+@end group
@group
symrec *
putsym (char const *name, int sym_type)
@{
symrec *res = (symrec *) malloc (sizeof (symrec));
- if (!res)
- abort ();
res->name = strdup (name);
- if (!res->name)
- abort ();
res->type = sym_type;
res->value.var = 0; /* Set value to 0 even if fun. */
res->next = sym_table;
@@ -2717,7 +2719,6 @@ operators in @code{yylex}.
@example
#include <ctype.h>
#include <stddef.h>
-#include <stdint.h>
@group
int
@@ -2764,15 +2765,8 @@ Bison generated a definition of @code{YYSTYPE} with a member named
/* If buffer is full, make it bigger. */
if (bufsize <= i)
@{
- ptrdiff_t maxsize
- = (PTRDIFF_MAX < SIZE_MAX
- ? PTRDIFF_MAX : SIZE_MAX);
- if ((maxsize - 40) / 2 < bufsize)
- abort ();
bufsize = 2 * bufsize + 40;
symbuf = realloc (symbuf, bufsize);
- if (!symbuf)
- abort ();
@}
/* Add this character to the buffer. */
symbuf[i++] = c;
--
2.21.0
>From 3e5268fc4429f0a51e1edbe6a9f6a4e2a3c343ae Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 3 Oct 2019 11:15:51 -0700
Subject: [PATCH 2/2] * doc/bison.texi (Table of Symbols): Mention memory
exhaustion.
---
doc/bison.texi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/doc/bison.texi b/doc/bison.texi
index a89142df..6f4ca9e2 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -14210,7 +14210,8 @@ is recovering from a syntax error, and 0 otherwise.
@deffn {Macro} YYSTACK_USE_ALLOCA
Macro used to control the use of @code{alloca} when the
deterministic parser in C needs to extend its stacks. If defined to 0,
-the parser will use @code{malloc} to extend its stacks. If defined to
+the parser will use @code{malloc} to extend its stacks and memory exhaustion
+occurs if @code{malloc} fails (@pxref{Memory Management}). If defined to
1, the parser will use @code{alloca}. Values other than 0 and 1 are
reserved for future Bison extensions. If not defined,
@code{YYSTACK_USE_ALLOCA} defaults to 0.
--
2.21.0