Re: Missing yypstate_clear prototype

Ryan <[email protected]>
Newsgroups gmane.comp.parsers.bison.bugs
Message-ID <[email protected]>
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)
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.