yacc.c: always initialize yylloc

The initial location might be used if the parser starts by an empty
reduction, so really ensure proper initialization of the initial
location.  The previous approach fails for PostgreSQL, which uses
Reported by Peter Eisentraut.
http://lists.gnu.org/archive/html/bug-bison/2012-11/msg00023.html
With help from Théophile Ranquet.

* data/yacc.c (b4_declare_scanner_communication_variables): Be sure
to initialize yylloc, even when its structure is unknown.
(yyparse): Simplify the call to b4_dollar_pushdef.
* tests/actions.at (Initial location): Check of similar pattern
as in the case of PostgreSQL.
This commit is contained in:
Theophile Ranquet
2012-11-19 10:43:56 +00:00
committed by Akim Demaille
parent 53e2cd1ebd
commit fb4c8a7cb9
4 changed files with 47 additions and 10 deletions

4
NEWS
View File

@@ -2,6 +2,10 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** Bug fixes
Warnings about uninitialized yylloc in yyparse have been fixed.
** Documentation
The sections about shift/reduce and reduce/reduce conflicts resolution

1
THANKS
View File

@@ -88,6 +88,7 @@ Pascal Bart pascal.bart@epita.fr
Paul Eggert eggert@cs.ucla.edu
Paul Hilfinger Hilfinger@CS.Berkeley.EDU
Per Allansson per@appgate.com
Peter Eisentraut peter_e@gmx.net
Peter Fales psfales@lucent.com
Peter Hamorsky hamo@upjs.sk
Peter Simons simons@cryp.to

View File

@@ -184,7 +184,8 @@ int yychar;
or non-GCC compilers. */
static YYSTYPE yyval_default;
# define YY_INITIAL_VALUE(Value) = Value
#endif]])[
#endif]b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -197,7 +198,7 @@ static YYSTYPE yyval_default;
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
/* Location data for the lookahead symbol. */
YYLTYPE yylloc][]b4_yyloc_default[;
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
]])b4_pure_if([], [[
/* Number of syntax errors so far. */
@@ -1410,7 +1411,8 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yypstate *yyps_local;]b4_pure_if([[
int yychar;
YYSTYPE yylval;]b4_locations_if([[
YYLTYPE yylloc][]b4_yyloc_default[;]])])[
static YYLTYPE yyloc_default][]b4_yyloc_default[;
YYLTYPE yylloc = yyloc_default;]])])[
if (yyps)
yyps_local = yyps;
else
@@ -1559,8 +1561,7 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yychar = YYEMPTY; /* Cause a token to be read. */
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [],
[m4_define([b4_at_dollar_used])dnl
b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
/* User initialization code. */
b4_user_initial_action
b4_dollar_popdef[]dnl

View File

@@ -73,8 +73,8 @@ AT_CLEANUP
## Initial location. ##
## ------------------ ##
# AT_TEST(SKELETON-NAME, DIRECTIVES)
# ----------------------------------
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
# -----------------------------------------------------------------------
# Check that the initial location is correct.
m4_pushdef([AT_TEST],
[AT_SETUP([Initial location: $1 $2])
@@ -85,7 +85,8 @@ AT_DATA_GRAMMAR([[input.y]],
%locations
%debug
%skeleton "$1"
$2
]$2[
]$3[
%parse-param { int x } // Useless, but used to force yyerror purity.
%code
{
@@ -122,8 +123,8 @@ main (void)
AT_FULL_COMPILE([input])
AT_PARSER_CHECK([./input], 1, [],
[[1.1
1.1: syntax error
[m4_default([$4], [1.1])
m4_default([$4], [1.1])[: syntax error
]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
@@ -138,6 +139,36 @@ AT_TEST([glr.c])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
## A very different test, based on PostgreSQL's implementation of the
## locations. See
## http://lists.gnu.org/archive/html/bug-bison/2012-11/msg00023.html
##
## Weirdly enough, to trigger the warning with GCC 4.7, we must not
## use fprintf, so run the test twice: once to check the warning
## (absence thereof), and another time to check the value.
AT_TEST([yacc.c], [%define api.pure],
[[%{
# define YYLTYPE int
# define YY_LOCATION_PRINT(Stream, Loc) \
(void) (Loc)
# define YYLLOC_DEFAULT(Current, Rhs, N) \
(Current) = ((Rhs)[N ? 1 : 0])
%}
]],
[@&t@])
AT_TEST([yacc.c], [%define api.pure],
[[%{
# define YYLTYPE int
# define YY_LOCATION_PRINT(Stream, Loc) \
fprintf ((Stream), "%d", (Loc))
# define YYLLOC_DEFAULT(Current, Rhs, N) \
(Current) = ((Rhs)[N ? 1 : 0])
%}
]],
[0])
m4_popdef([AT_TEST])