I looked into the matter further, and it turns out that GCC has two classes of warnings in this area, -Wuninitialized and -Wmaybe-uninitialized. It's the latter that are causing trouble, and initializing yylval suppresses them; but it also suppresses the trouble-free warnings, which is undesirable.
So, how about the following idea instead? It follows your suggestion for random compilers, but for new-enough GCC it simply disables the bogus warning directly. This should cause recent GCC to issue a warning for my most-recent test grammar (which is what we prefer) while not issuing warnings for the cases where warnings are bothering people. >From 41eb9c0b8568ab9cc79395fa27dce6b2646379a3 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Fri, 5 Oct 2012 10:41:51 -0700 Subject: [PATCH] yacc: suppress unwanted GCC -Wmaybe-uninitalized diagnostic * data/yacc.c (YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN) (YY_IGNORE_MAYBE_UNINITIALIZED_END, YYLVAL_INITIALIZE): New macros. Use them to suppress an unwanted GCC diagnostic. --- data/yacc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/data/yacc.c b/data/yacc.c index 44f96dd..e5fc28c 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -172,6 +172,28 @@ m4_define([b4_declare_scanner_communication_variables], [[ /* The lookahead symbol. */ int yychar; +]b4_pure_if([[ +#if defined __GNUC__ && (4 < __GNUC__ + (6 <= __GNUC_MINOR__)) +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +static YYSTYPE yyval_default; +# define YYLVAL_INITIALIZE() (yylval = yyval_default) +#endif]])[ +#ifndef YYLVAL_INITIALIZE +# define YYLVAL_INITIALIZE() +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif + /* The semantic value of the lookahead symbol. */ YYSTYPE yylval;]b4_locations_if([[ @@ -1456,6 +1478,8 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[ yyvsp = yyvs;]b4_locations_if([[ yylsp = yyls; + YYLVAL_INITIALIZE (); + #if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[; @@ -1641,7 +1665,9 @@ yyread_pushed_token:]])[ YY_LAC_DISCARD ("shift");]])[ yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END ]b4_locations_if([ *++yylsp = yylloc;])[ goto yynewstate; @@ -1861,7 +1887,9 @@ yyerrlab1: current lookahead token, the shift below will for sure. */ YY_LAC_DISCARD ("error recovery");]])[ + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END ]b4_locations_if([[ yyerror_range[2] = yylloc; /* Using YYLLOC is tempting, but would change the location of -- 1.7.11.4
