Wonderful, thank you very much! Ryan
On Mon, Jun 01, 2020 at 08:51:05AM +0200, Akim Demaille wrote: > Hi Ryan, > > > Le 29 mai 2020 à 15:35, Ryan <[email protected]> a écrit : > > > > I have hit a missing prototype warning for yypstate_clear() after > > upgrading my bison installation to 3.6.2. > > > > I have a reproducing example (not a particularly small one) in my > > repository, by curling the following url: > > > > https://git.sr.ht/~splintermail-dev/splintermail-client/blob/dev/libimap/parse.y > > > > Then the generated file (bison parse.y -o parse.tab.c) has a > > yypstate_clear function with no prototype. > > Thanks for the report! Sorry about that, we should have set these > warnings on a long time ago. It took me quite a while to address > because it triggered many other warnings I had to take care of. > The CI is still not completely green, but I think it's own the right > track now. > > So I will install this asap. Then I should release 3.6.3 with the > fix. > > Cheers! > > > > commit 52ce2a008bb32e686151c3c58739ff4fcd17f83d > Author: Akim Demaille <[email protected]> > Date: Sun May 31 12:56:02 2020 +0200 > > build: check -Wmissing-prototypes > > pstate_clear is lacking a prototype. > Reported by Ryan > https://lists.gnu.org/r/bug-bison/2020-05/msg00101.html > > Besides, none of the C examples were compiled with the warning flags. > > * configure.ac (warn_c): Add -Wmissing-prototypes. > * data/skeletons/yacc.c (pstate_clear): Make it static. > * examples/local.mk (TEST_CFLAGS): New. > * examples/c/bistromathic/local.mk, examples/c/calc/local.mk, > * examples/c/lexcalc/local.mk, examples/c/mfcalc/local.mk, > * examples/c/pushcalc/local.mk, examples/c/reccalc/local.mk, > * examples/c/rpcalc/local.mk: > Use it. > > GCC's warn_unused_result is not silenced by a cast to void, so we have > to "use" scanf's result. > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 > > Flex generated code produces too many warnings, including things such > as, with ICC: > > examples/c/lexcalc/scan.c(1088): error #1682: implicit conversion > of a 64-bit integral type to a smaller integral type > (potential portability problem) > 2259 YY_INPUT( > (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), > 2260 ^ > 2261 > 2262 > > I am tired of trying to fix Flex's output. The project does not seem > maintained. We ought to avoid it. So, for the time being, don't try > to enable warnings with Flex. > > * examples/c/bistromathic/parse.y, examples/c/reccalc/scan.l: Fix > warnings. > * doc/bison.texi: Discard scanf's return value to defeat > -Werror=unused-result. > > diff --git a/NEWS b/NEWS > index f5eb8032..fe2bae30 100644 > --- a/NEWS > +++ b/NEWS > @@ -2,6 +2,13 @@ GNU Bison NEWS > > * Noteworthy changes in release ?.? (????-??-??) [?] > > +** Bug fixes > + > + Incorrect comments in the generated parsers. > + > + Warnings in push parsers (yacc.c). > + > + Incorrect display of gotos in LAC traces (lalr1.cc). > > * Noteworthy changes in release 3.6.2 (2020-05-17) [stable] > > diff --git a/THANKS b/THANKS > index 48b31ea9..36df5e29 100644 > --- a/THANKS > +++ b/THANKS > @@ -162,6 +162,7 @@ Quoc Peyrot [email protected] > R Blake [email protected] > Raja R Harinath [email protected] > Ralf Wildenhues [email protected] > +Ryan [email protected] > Rich Wilson [email protected] > Richard Stallman [email protected] > Rici Lake [email protected] > diff --git a/configure.ac b/configure.ac > index edc05eb5..32304603 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -135,7 +135,9 @@ if test "$enable_gcc_warnings" = yes; then > -Wpointer-arith -Wshadow > -Wwrite-strings > -wr188 -wr2259 -wr3179' > - warn_c='-Wbad-function-cast -Wstrict-prototypes' > + warn_c='-Wbad-function-cast > + -Wmissing-prototypes > + -Wstrict-prototypes' > warn_cxx='-Wextra-semi -Wnoexcept -Wold-style-cast > -Wundefined-func-template > -Wweak-vtables' > # Warnings for the test suite only. > diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c > index a9f15c8d..bd5e7d84 100644 > --- a/data/skeletons/yacc.c > +++ b/data/skeletons/yacc.c > @@ -1480,7 +1480,7 @@ yypull_parse (yypstate *yyps]b4_user_formals[) > ]b4_parse_state_variable_macros([b4_pstate_macro_define])[ > > /* Initialize the parser data structure. */ > -void > +static void > yypstate_clear (yypstate *yyps) > { > ]b4_initialize_parser_state_variables[ > diff --git a/doc/bison.texi b/doc/bison.texi > index 726cbf22..29b51a25 100644 > --- a/doc/bison.texi > +++ b/doc/bison.texi > @@ -1879,6 +1879,7 @@ Here is the code for the lexical analyzer: > and tabs, and returns 0 for end-of-input. */ > > #include <ctype.h> > +#include <stdlib.h> > @end group > > @group > @@ -1895,7 +1896,8 @@ yylex (void) > if (c == '.' || isdigit (c)) > @{ > ungetc (c, stdin); > - scanf ("%lf", &yylval); > + if (scanf ("%lf", &yylval) != 1) > + abort (); > return NUM; > @} > @end group > @@ -2728,7 +2730,8 @@ yylex (void) > if (c == '.' || isdigit (c)) > @{ > ungetc (c, stdin); > - scanf ("%lf", &yylval.NUM); > + if (scanf ("%lf", &yylval.NUM) != 1) > + abort (); > return NUM; > @} > @end group > @@ -2755,10 +2758,10 @@ Bison generated a definition of @code{YYSTYPE} with a > member named > if (bufsize <= i) > @{ > bufsize = 2 * bufsize + 40; > - symbuf = realloc (symbuf, bufsize); > + symbuf = realloc (symbuf, (size_t) bufsize); > @} > /* Add this character to the buffer. */ > - symbuf[i++] = c; > + symbuf[i++] = (char) c; > /* Get another character. */ > c = getchar (); > @} > @@ -10629,7 +10632,7 @@ when there were errors. No file was generated > (except the reports generated > by @option{--verbose}, etc.). In particular, the output files that possibly > existed were not changed. > > -@item 63 (mistmatch) > +@item 63 (mismatch) > when @command{bison} does not meet the version requirements of the grammar > file. @xref{Require Decl}. No file was generated or changed. > @end table > @@ -15269,6 +15272,7 @@ London, Department of Computer Science, TR-00-12 > (December 2000). > @c LocalWords: YYUNDEF SymbolKind yypcontext YYENOMEM TOKENMAX getBundle > @c LocalWords: ResourceBundle myResources getString getName getToken > @c LocalWords: getLocation getExpectedTokens reportSyntaxError bistromathic > +@c LocalWords: TokenKind > > @c Local Variables: > @c ispell-dictionary: "american" > diff --git a/examples/c/bistromathic/local.mk > b/examples/c/bistromathic/local.mk > index cad0425b..e9801ab2 100644 > --- a/examples/c/bistromathic/local.mk > +++ b/examples/c/bistromathic/local.mk > @@ -31,6 +31,7 @@ if ENABLE_BISTROMATHIC > -DBISON_LOCALEDIR='"$(localdir)"' \ > -DLOCALEDIR='"$(localdir)"' \ > -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > + %C%_bistromathic_CFLAGS = $(TEST_CFLAGS) > %C%_bistromathic_LDADD = -lm $(LIBREADLINE) $(LIBINTL) > endif > > diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y > index c2ddb124..246aa3d5 100644 > --- a/examples/c/bistromathic/parse.y > +++ b/examples/c/bistromathic/parse.y > @@ -1,7 +1,6 @@ > %require "3.6" > > %code top { > - #include <assert.h> > #include <ctype.h> // isdigit > #include <locale.h> // LC_ALL > #include <math.h> // cos, sin, etc. > @@ -218,7 +217,7 @@ getsym (char const *name) > } > > // How many symbols are registered. > -int > +static int > symbol_count (void) > { > int res = 0; > @@ -312,7 +311,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE > *yylloc) > `---------*/ > > > -const char * > +static const char * > error_format_string (int argc) > { > switch (argc) > @@ -407,7 +406,8 @@ xstrndup (const char *string, size_t n) > const char *end = memchr (string, '\0', n); > size_t len = end ? (size_t) (end - string) : n; > char *new = malloc (len + 1); > - assert (new); > + if (!new) > + abort (); > new[len] = '\0'; > return memcpy (new, string, len); > } > @@ -418,7 +418,8 @@ xstrndup (const char *string, size_t n) > `-----------*/ > > // Parse (and execute) this line. > -int process_line (YYLTYPE *lloc, const char *line) > +static int > +process_line (YYLTYPE *lloc, const char *line) > { > yypstate *ps = yypstate_new (); > int status = 0; > @@ -433,7 +434,8 @@ int process_line (YYLTYPE *lloc, const char *line) > } > > // Get the list of possible tokens after INPUT was read. > -int > +// Returns a nonnegative. > +static int > expected_tokens (const char *input, > int *tokens, int ntokens) > { > @@ -454,6 +456,8 @@ expected_tokens (const char *input, > > // Then query for the accepted tokens at this point. > int res = yypstate_expected_tokens (ps, tokens, ntokens); > + if (res < 0) > + abort (); > yypstate_delete (ps); > return res; > } > @@ -463,7 +467,7 @@ expected_tokens (const char *input, > // TEXT is the word to complete. We can use the entire contents of > // rl_line_buffer in case we want to do some simple parsing. Return > // the array of matches, or NULL if there aren't any. > -char ** > +static char ** > completion (const char *text, int start, int end) > { > YYDPRINTF ((stderr, "completion (\"%.*s[%.*s]%s\")\n", > @@ -473,14 +477,17 @@ completion (const char *text, int start, int end) > > // Get list of token numbers. > int tokens[YYNTOKENS]; > - char *line = xstrndup (rl_line_buffer, start); > + char *line = xstrndup (rl_line_buffer, (size_t) start); > int ntokens = expected_tokens (line, tokens, YYNTOKENS); > free (line); > > // Build MATCHES, the list of possible completions. > - const int len = strlen (text); > + const size_t len = strlen (text); > // Need initial prefix and final NULL. > - char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches); > + char **matches > + = calloc ((size_t) ntokens + (size_t) symbol_count () + 2, sizeof > *matches); > + if (!matches) > + abort (); > int match = 1; > for (int i = 0; i < ntokens; ++i) > switch (tokens[i]) > @@ -510,9 +517,9 @@ completion (const char *text, int start, int end) > matches[0] = strdup (text); > else > { > - int lcplen = strlen (matches[1]); > + size_t lcplen = strlen (matches[1]); > for (int i = 2; i < match && lcplen; ++i) > - for (int j = 0; j < lcplen; ++j) > + for (size_t j = 0; j < lcplen; ++j) > if (matches[1][j] != matches[i][j]) > lcplen = j; > matches[0] = xstrndup (matches[1], lcplen); > @@ -536,7 +543,8 @@ completion (const char *text, int start, int end) > return matches; > } > > -void init_readline (void) > +static void > +init_readline (void) > { > // Allow conditional parsing of the ~/.inputrc file. > rl_readline_name = "bistromathic"; > @@ -555,7 +563,8 @@ void init_readline (void) > | Main. | > `-------*/ > > -int main (int argc, char const* argv[]) > +int > +main (int argc, char const* argv[]) > { > #if defined ENABLE_NLS && ENABLE_NLS > // Set up internationalization. > diff --git a/examples/c/calc/calc.y b/examples/c/calc/calc.y > index 7757648d..97e352a0 100644 > --- a/examples/c/calc/calc.y > +++ b/examples/c/calc/calc.y > @@ -1,6 +1,7 @@ > %code top { > #include <ctype.h> /* isdigit. */ > - #include <stdio.h> /* For printf, etc. */ > + #include <stdio.h> /* printf. */ > + #include <stdlib.h> /* abort. */ > #include <string.h> /* strcmp. */ > > int yylex (void); > @@ -73,7 +74,8 @@ yylex (void) > if (c == '.' || isdigit (c)) > { > ungetc (c, stdin); > - scanf ("%lf", &yylval.NUM); > + if (scanf ("%lf", &yylval.NUM) != 1) > + abort (); > return NUM; > } > > diff --git a/examples/c/calc/local.mk b/examples/c/calc/local.mk > index 14b78f3b..503b034a 100644 > --- a/examples/c/calc/local.mk > +++ b/examples/c/calc/local.mk > @@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y > > # Don't use gnulib's system headers. > %C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > +%C%_calc_CFLAGS = $(TEST_CFLAGS) > > dist_calc_DATA = %D%/calc.y %D%/Makefile %D%/README.md > CLEANFILES += %D%/calc.[ch] %D%/calc.output %D%/scan.c > diff --git a/examples/c/lexcalc/local.mk b/examples/c/lexcalc/local.mk > index 0acd2607..b73887e2 100644 > --- a/examples/c/lexcalc/local.mk > +++ b/examples/c/lexcalc/local.mk > @@ -25,6 +25,8 @@ if FLEX_WORKS > nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l > # Don't use gnulib's system headers. > %C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > + # Fighting warnings triggered by Flex is just too painful. > + # %C%_lexcalc_CFLAGS = $(TEST_CFLAGS) > endif FLEX_WORKS > > %D%/parse.c: $(dependencies) > diff --git a/examples/c/lexcalc/scan.l b/examples/c/lexcalc/scan.l > index d66a23cf..708fd28b 100644 > --- a/examples/c/lexcalc/scan.l > +++ b/examples/c/lexcalc/scan.l > @@ -4,7 +4,7 @@ > %option nodefault noinput nounput noyywrap > > %{ > -#include <errno.h> /* errno, ERANGE */ > +#include <errno.h> /* errno, ERANGE */ > #include <limits.h> /* INT_MIN */ > #include <stdlib.h> /* strtol */ > > @@ -12,7 +12,7 @@ > > // Each time a rule is matched, advance the end cursor/position. > #define YY_USER_ACTION \ > - yylloc->last_column += yyleng; > + yylloc->last_column += (int) yyleng; > > // Move the first position onto the last. > #define LOCATION_STEP() \ > diff --git a/examples/c/mfcalc/local.mk b/examples/c/mfcalc/local.mk > index 2c0fcb5e..69c91f71 100644 > --- a/examples/c/mfcalc/local.mk > +++ b/examples/c/mfcalc/local.mk > @@ -31,6 +31,7 @@ nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources) > %D%/mfcalc.c: $(dependencies) > # Don't use gnulib's system headers. > %C%_mfcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > +%C%_mfcalc_CFLAGS = $(TEST_CFLAGS) > %C%_mfcalc_LDADD = -lm > > dist_TESTS += %D%/mfcalc.test > diff --git a/examples/c/pushcalc/calc.y b/examples/c/pushcalc/calc.y > index 7b0b9996..6d49470c 100644 > --- a/examples/c/pushcalc/calc.y > +++ b/examples/c/pushcalc/calc.y > @@ -1,7 +1,7 @@ > %code top { > #include <ctype.h> /* isdigit. */ > - #include <stdbool.h> > - #include <stdio.h> /* For printf, etc. */ > + #include <stdio.h> /* printf. */ > + #include <stdlib.h> /* abort. */ > #include <string.h> /* strcmp. */ > } > > @@ -81,7 +81,8 @@ yylex (YYSTYPE *yylval) > if (c == '.' || isdigit (c)) > { > ungetc (c, stdin); > - scanf ("%lf", &yylval->NUM); > + if (scanf ("%lf", &yylval->NUM) != 1) > + abort (); > return NUM; > } > > diff --git a/examples/c/pushcalc/local.mk b/examples/c/pushcalc/local.mk > index 9b6b19d6..7f53a0c1 100644 > --- a/examples/c/pushcalc/local.mk > +++ b/examples/c/pushcalc/local.mk > @@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y > > # Don't use gnulib's system headers. > %C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > +%C%_calc_CFLAGS = $(TEST_CFLAGS) > > dist_pushcalc_DATA = %D%/calc.y %D%/Makefile %D%/README.md > CLEANFILES += %D%/calc.[ch] %D%/calc.output > diff --git a/examples/c/reccalc/local.mk b/examples/c/reccalc/local.mk > index 0538f120..41a12828 100644 > --- a/examples/c/reccalc/local.mk > +++ b/examples/c/reccalc/local.mk > @@ -26,6 +26,8 @@ if FLEX_WORKS > BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES) > # Don't use gnulib's system headers. > %C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D% > + # Fighting warnings triggered by Flex is just too painful. > + # %C%_reccalc_CFLAGS = $(TEST_CFLAGS) > endif FLEX_WORKS > > %D%/parse.c: $(dependencies) > diff --git a/examples/c/reccalc/scan.l b/examples/c/reccalc/scan.l > index 0bf5210c..45d70d3b 100644 > --- a/examples/c/reccalc/scan.l > +++ b/examples/c/reccalc/scan.l > @@ -32,9 +32,9 @@ > do \ > capacity = capacity ? 2 * capacity : 128; \ > while (capacity < size + yyleng + 1); \ > - str = realloc (str, capacity); \ > + str = realloc (str, (size_t) capacity); \ > } \ > - memcpy (str + size, yytext, yyleng); \ > + memcpy (str + size, yytext, (size_t) yyleng); \ > size += yyleng; \ > assert (size < capacity); \ > } while (0) > diff --git a/examples/c/rpcalc/local.mk b/examples/c/rpcalc/local.mk > index f10f7c19..0c3bfd8a 100644 > --- a/examples/c/rpcalc/local.mk > +++ b/examples/c/rpcalc/local.mk > @@ -31,6 +31,7 @@ nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources) > %D%/rpcalc.c: $(dependencies) > # Don't use gnulib's system headers. > %C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D% > +%C%_rpcalc_CFLAGS = $(TEST_CFLAGS) > %C%_rpcalc_LDADD = -lm > > dist_TESTS += %D%/rpcalc.test > diff --git a/examples/local.mk b/examples/local.mk > index 854a5da4..51c2c5a2 100644 > --- a/examples/local.mk > +++ b/examples/local.mk > @@ -35,6 +35,9 @@ > dist_noinst_SCRIPTS = %D%/extexi %D%/test > TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test > > +TEST_CFLAGS = \ > + $(WARN_CFLAGS) $(WARN_CFLAGS_TEST) $(WERROR_CFLAGS) > + > AM_CXXFLAGS = \ > $(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS) > >
