bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bison-2.6.4-generated parser triggers pragma warnings in GCC 6.4.3


From: Akim Demaille
Subject: Re: bison-2.6.4-generated parser triggers pragma warnings in GCC 6.4.3
Date: Thu, 25 Oct 2012 11:16:20 +0200

Le 24 oct. 2012 à 17:40, Peter Simons a écrit :

> Hi,

Hi Peter,

> after updating to Bison version 2.6.4, I can no longer build Grub 2.00 because
> of the following warnings:
> 
>  grub_script.tab.c: In function 'grub_script_yyparse':
>  grub_script.tab.c:1534:3: error: unknown option after '#pragma GCC 
> diagnostic' kind [-Werror=pragmas]
>  grub_script.tab.c:2168:3: error: unknown option after '#pragma GCC 
> diagnostic' kind [-Werror=pragmas]
>  cc1: all warnings being treated as errors

Thanks, I have been able to reproduce your problem.

Actually, I installed a much wider range of GCC versions, and
GCC 4.6 is not even able to compile Bison itself, and only
GCC 4.2, 4.7 and 4.8, and Clang, were able to run the Bison test
suite without any failure: 4.3, 4.4, 4.5, and 4.6 all fail.

There are several different failures.

The GCC 4.6 failures are exactly the one you describe: they
fail to recognize the Pragmas that are expected to be supported,
so the package does not even build.

The GCC 4.3 failures include:

> #                             -*- compilation -*-
> 187. calc.at:644: testing Calculator %define api.push-pull both %define 
> api.pure %locations ...
> ../../../tests/calc.at:644: bison -o calc.c calc.y
> ../../../tests/calc.at:644: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c 
> $LIBS
> stderr:
> cc1: warnings being treated as errors
> calc.c: In function 'yypush_parse':
> calc.c:1369: error: 'yylloc.last_line' may be used uninitialized in this 
> function
> calc.c:1369: error: 'yylloc.first_line' may be used uninitialized in this 
> function
> calc.c:1369: error: 'yylloc.last_column' may be used uninitialized in this 
> function
> calc.c:1369: error: 'yylloc.first_column' may be used uninitialized in this 
> function

The warning is valid reading the code:

>   YYLTYPE yylloc;
>   [...]
>   if (!yyps->yynew)
>     {
>       yyn = yypact[yystate];
>       goto yyread_pushed_token;
>     }
>   [...]
> #if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
>   /* Initialize the default location before parsing starts.  */
>   yylloc.first_line   = yylloc.last_line   = 1;
>   yylloc.first_column = yylloc.last_column = 1;
> #endif

> yyread_pushed_token:
>       YYDPRINTF ((stderr, "Reading a token: "));
>       yychar = yypushed_char;
>       if (yypushed_val)
>         yylval = *yypushed_val;
>       if (yypushed_loc)
>         yylloc = *yypushed_loc;

so indeed, yylloc must not be initialized when not calling yyparse
for the first time.  In this setup, unless GCC is ultra smart and
follows the possible initialization of yypushed_loc, the warning
must happen, even when things are properly programmed.  So, even
if that means in small lose of efficiency, I would like to initialize
yylloc when defined:

>   YYLTYPE yylloc;
> #if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
>   /* Initialize the default location before parsing starts.  */
>   yylloc.first_line   = yylloc.last_line   = 1;
>   yylloc.first_column = yylloc.last_column = 1;
> #endif

or better, with a static variable properly initialized.

GCC 4.3 also fails on this:

> #                             -*- compilation -*-
> 328. push.at:24: testing Memory Leak for Early Deletion ...
> ../../../tests/push.at:73: bison -o input.c input.y
> ../../../tests/push.at:74: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c 
> $LIBS
> stderr:
> cc1: warnings being treated as errors
> input.c: In function 'yypush_parse':
> input.c:1172: error: 'yylval' may be used uninitialized in this function
> stdout:
> ../../../tests/push.at:74: exit code was 1, expected 0
> 328. push.at:24: 328. Memory Leak for Early Deletion (push.at:24): FAILED 
> (push.at:74)

which shows that Paul's approach to initialize yylval quite
late (I had proposed to do it directly in the definition of
the variable) fails for it.  That's actually very consistent
with the previous failure.

GCC 4.4 has the same failures, but some new ones:

> #                             -*- compilation -*-
> 236. torture.at:465: testing Exploding the Stack Size with Alloca ...
> ../../../tests/torture.at:474: bison -o input.c input.y
> ../../../tests/torture.at:474: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input 
> input.c $LIBS
> stderr:
> cc1: warnings being treated as errors
> input.y: In function 'main':
> input.y:60: error: 'status' may be used uninitialized in this function
> stdout:
> ../../../tests/torture.at:474: exit code was 1, expected 0
> 236. torture.at:465: 236. Exploding the Stack Size with Alloca 
> (torture.at:465): FAILED (torture.at:474)

that's a test suite only issue, the test reads:

> int
> main (int argc, const char **argv)
> {
>   YYSTYPE yylval_init = get_args (argc, argv);
>   int status;
>   int count;
>   yydebug = 1;
>   for (count = 0; count < 2; ++count)
>     {
>       int new_status;
>       yylval = yylval_init;
>       new_status = yyparse ();
>       if (count == 0)
>         status = new_status;
>       else
>         assert (new_status == status);
>     }
>   return status;
> }

I don't know why more recent versions of the compiler do not
show this error: do they manage to actually see that the
assignment of status will always be run?

Gcc 4.4 also adds real new failures:

> #                             -*- compilation -*-
> 335. push.at:24: testing Memory Leak for Early Deletion ...
> ../../../tests/push.at:73: bison -o input.c input.y
> ../../../tests/push.at:74: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c 
> $LIBS
> stderr:
> cc1: warnings being treated as errors
> input.c: In function 'yypush_parse':
> input.c:1172: error: 'yylval' may be used uninitialized in this function
> stdout:
> ../../../tests/push.at:74: exit code was 1, expected 0
> 335. push.at:24: 335. Memory Leak for Early Deletion (push.at:24): FAILED 
> (push.at:74)


OS X's native Clang also has plenty of failures because of this:

> $ cat /tmp/foo.c
> class foo {};
> int main () {}
> $ clang++ -Wall /tmp/foo.c
> clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior 
> is deprecated


So, I plan to:
- raise the GCC requirement for Pragmas from 4.6 to 4.7
- define yylval and yylloc with a value, instead of assigning
  later

I am personally still not convinced of the benefits of leaving
these variables uninitialized (testing quickly shows if some
value is random, especially in the context of a parser where
being initialized just means that you have the first assignment,
but what counts is to be set for each call to yylex, not just
the first one), so Paul, if you now think this material is less
secure than what was expected, then let me know, and I'll fall
back to the same scheme for every configuration.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]