Re: Missing yypstate_clear prototype

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.bugs
Message-ID <[email protected]>
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.