From cf8067530b3e075230051d459782a1074db5b211 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 6 Oct 2006 06:57:00 +0000 Subject: [PATCH] Fix test failure reported by Tom Lane in and try to make such failures easier to catch in the future. * data/glr.c (YYTRANSLATE): Don't check for nonpositive arg; that's now the caller's responsibility. (yyprocessOneStack, yyrecoverSyntaxError, yyparse): Set yychar = YYEOF if it's negative. * tests/actions.at (yylex): Abort if asked to read past EOF. * tests/conflicts.at (yylex): Likewise. * tests/cxx-type.at (yylex): Likewise. * tests/glr-regression.at (yylex): Likewise. * tests/input.at (yylex): Likewise. * tests/regression.at (yylex): Likewise. * tests/torture.at (yylex): Likewise. --- ChangeLog | 17 ++++++ data/glr.c | 39 +++++++++++--- tests/actions.at | 45 ++++++++++++---- tests/conflicts.at | 15 +++--- tests/cxx-type.at | 2 + tests/glr-regression.at | 112 ++++++++++++++++++++++++++++------------ tests/input.at | 9 ++-- tests/regression.at | 19 +++++-- tests/torture.at | 17 ++++-- 9 files changed, 203 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 478c6e40..a7da5b4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-10-05 Paul Eggert + + Fix test failure reported by Tom Lane in + + and try to make such failures easier to catch in the future. + * data/glr.c (YYTRANSLATE): Don't check for nonpositive arg; + that's now the caller's responsibility. + (yyprocessOneStack, yyrecoverSyntaxError, yyparse): + Set yychar = YYEOF if it's negative. + * tests/actions.at (yylex): Abort if asked to read past EOF. + * tests/conflicts.at (yylex): Likewise. + * tests/cxx-type.at (yylex): Likewise. + * tests/glr-regression.at (yylex): Likewise. + * tests/input.at (yylex): Likewise. + * tests/regression.at (yylex): Likewise. + * tests/torture.at (yylex): Likewise. + 2006-10-01 Paul Eggert Fix problems with translating English-language diagnostics. diff --git a/data/glr.c b/data/glr.c index 7c3d998d..49137c1a 100644 --- a/data/glr.c +++ b/data/glr.c @@ -346,8 +346,7 @@ static YYSTYPE yyval_default; #define YYMAXUTOK ]b4_user_token_number_max[ #define YYTRANSLATE(YYX) \ - ((YYX <= 0) ? YYEOF : \ - (unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const ]b4_int_type_for([b4_translate])[ yytranslate[] = @@ -2040,11 +2039,19 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk, { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } - else - yytoken = YYTRANSLATE (yychar); + yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts); while (*yyconflicts != 0) @@ -2210,8 +2217,16 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[) } YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } yyj = yypact[yystackp->yytops.yystates[0]->yylrState]; if (yyis_pact_ninf (yyj)) return; @@ -2363,11 +2378,19 @@ m4_popdef([b4_at_dollar])])dnl { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } - else - yytoken = YYTRANSLATE (yychar); + yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts); if (*yyconflicts != 0) break; diff --git a/tests/actions.at b/tests/actions.at index fad7f77b..aa418b1f 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -55,8 +55,11 @@ exp: { putchar ('0'); } static int yylex (void) { - static const char *input = "123456789"; - return *input++; + static char const input[] = "123456789"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } static void @@ -131,6 +134,9 @@ sum_of_the_five_previous_values: static int yylex (void) { + static int called; + if (called++) + abort (); return EOF; } @@ -175,6 +181,7 @@ AT_DATA_GRAMMAR([[input.y]], [[%start-header { #include #include +#include #include #define YYINITDEPTH 10 @@ -310,6 +317,8 @@ yylex (]AT_LEX_FORMALS[) AT_LOC.last_line = AT_LOC.last_column = AT_LOC.first_line + 9; ])[ + if (! (0 <= c && c <= strlen (source))) + abort (); if (source[c]) printf ("sending: '%c'", source[c]); else @@ -623,11 +632,13 @@ start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ; static int yylex (void) { - static const char *input = "abcd"; - static int column = 1; - yylval = *input++; + static char const input[] = "abcd"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + yylval = input[toknum++]; yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = column++; + yylloc.first_column = yylloc.last_column = toknum; return yylval; } @@ -741,8 +752,11 @@ start: static int yylex (void) { - static const char *input = "abcdef"; - return *input++; + static char const input[] = "abcdef"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } static void @@ -851,6 +865,9 @@ start: { $$ = 'S'; } ; static int yylex (void) { + static int called; + if (called++) + abort (); yylval = 'E'; yylloc.first_line = yylloc.last_line = 1; yylloc.first_column = yylloc.last_column = 1; @@ -915,6 +932,7 @@ AT_DATA_GRAMMAR([[input.y]], %{ # include +# include static void yyerror (const char *msg); static int yylex (void); # define USE(SYM) @@ -941,8 +959,11 @@ start: static int yylex (void) { - static const char *input = "abd"; - yylval = *input++; + static char const input[] = "abd"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + yylval = input[toknum++]; return yylval; } @@ -1025,6 +1046,7 @@ AT_DATA_GRAMMAR([[input.y]], %{ # include +# include static void yyerror (const char *msg); static int yylex (void); # define USE(SYM) @@ -1051,6 +1073,9 @@ start: { USE($$); } ; static int yylex (void) { + static int called; + if (called++) + abort (); return 0; } diff --git a/tests/conflicts.at b/tests/conflicts.at index 1cbf23ac..436ba858 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -56,6 +56,7 @@ AT_DATA_GRAMMAR([input.y], %{ #include #include +#include #define YYERROR_VERBOSE 1 static void @@ -65,16 +66,15 @@ yyerror (const char *msg) } /* The current argument. */ -static const char *input = NULL; +static const char *input; static int yylex (void) { - /* No token stands for end of file. */ - if (input && *input) - return *input++; - else - return 0; + static size_t toknum; + if (! (toknum <= strlen (input))) + abort (); + return input[toknum++]; } %} @@ -90,8 +90,7 @@ expr: expr '<' expr int main (int argc, const char *argv[]) { - if (argc > 1) - input = argv[1]; + input = argc <= 1 ? "" : argv[1]; return yyparse (); } ]]) diff --git a/tests/cxx-type.at b/tests/cxx-type.at index b716a1d4..26045728 100644 --- a/tests/cxx-type.at +++ b/tests/cxx-type.at @@ -163,6 +163,8 @@ yylex (LEX_PARAMETERS) while (1) { + if (feof (stdin)) + abort (); c = getchar (); switch (c) { diff --git a/tests/glr-regression.at b/tests/glr-regression.at index 28a7044b..31a60169 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -30,6 +30,7 @@ AT_DATA_GRAMMAR([glr-regr1.y], %{ #include +#include #define YYSTYPE int static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1); @@ -82,7 +83,10 @@ yylex (void) { for (;;) { - int ch = getchar (); + int ch; + if (feof (stdin)) + abort (); + ch = getchar (); if (ch == EOF) return 0; else if (ch == 'B' || ch == 'P') @@ -168,13 +172,15 @@ var_printer: 'v' %% -FILE *input = NULL; +FILE *input; int yylex (void) { char buf[50]; char *s; + if (feof (stdin)) + abort (); switch (fscanf (input, " %1[a-z,]", buf)) { case 1: return buf[0]; @@ -237,6 +243,7 @@ AT_DATA_GRAMMAR([glr-regr3.y], %{ #include +#include #include static int MergeRule (int x0, int x1); @@ -299,6 +306,8 @@ int T[] = { T1, T2, T3, T4 }; int yylex (void) { char inp[3]; + if (feof (stdin)) + abort (); if (fscanf (input, "%2s", inp) == EOF) return 0; switch (inp[0]) @@ -375,8 +384,11 @@ B: 'a' { $$ = make_value ("B", "'a'"); } ; static int yylex (void) { - static char const *input = "a"; - return *input++; + static char const input[] = "a"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } int @@ -465,8 +477,11 @@ start: static int yylex (void) { - static char const *input = "a"; - return *input++; + static char const input[] = "a"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } static void @@ -527,8 +542,11 @@ start: 'a' | 'a' ; static int yylex (void) { - static char const *input = "a"; - return *input++; + static char const input[] = "a"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } static void @@ -697,6 +715,8 @@ int yylex (void) lexIndex += 1; switch (lexIndex) { + default: + abort (); case 1: yylloc.first_column = 1; yylloc.last_column = 9; @@ -705,7 +725,7 @@ int yylex (void) yylloc.first_column = 13; yylloc.last_column = 17; return T_PORT; - default: + case 3: return 0; } } @@ -822,6 +842,7 @@ AT_SETUP([Corrupted semantic options if user action cuts parse]) AT_DATA_GRAMMAR([glr-regr10.y], [[ %{ +# include # include static void yyerror (char const *); static int yylex (void); @@ -851,6 +872,9 @@ yyerror (char const *msg) static int yylex (void) { + static int called; + if (called++) + abort (); return 0; } @@ -913,8 +937,11 @@ yyerror (char const *msg) static int yylex (void) { - static char const *input = "a"; - return *input++; + static char const input[] = "a"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + return input[toknum++]; } int @@ -1030,10 +1057,12 @@ static int yylex (void) { static int const input[] = { PARENT_RHS_AFTER, 0 }; - static const int *inputp = input; - if (*inputp == PARENT_RHS_AFTER) + static size_t toknum; + if (! (toknum < sizeof input / sizeof *input)) + abort (); + if (input[toknum] == PARENT_RHS_AFTER) parent_rhs_after_value = 1; - return *inputp++; + return input[toknum++]; } int @@ -1149,12 +1178,14 @@ yyerror (char const *msg) static int yylex (void) { - static char const *input = "ab"; - static int i = 0; + static char const input[] = "ab"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = i + 1; - yylval.value = input[i] + 'A' - 'a'; - return input[i++]; + yylloc.first_column = yylloc.last_column = toknum + 1; + yylval.value = input[toknum] + 'A' - 'a'; + return input[toknum++]; } static void @@ -1235,6 +1266,7 @@ AT_DATA_GRAMMAR([glr-regr14.y], %union { char value; } %{ + #include #include static void yyerror (char const *); static int yylex (void); @@ -1355,12 +1387,14 @@ yyerror (char const *msg) static int yylex (void) { - static char const *input = "abcdddd"; - static int i = 0; + static char const input[] = "abcdddd"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = i + 1; - yylval.value = input[i] + 'A' - 'a'; - return input[i++]; + yylloc.first_column = yylloc.last_column = toknum + 1; + yylval.value = input[toknum] + 'A' - 'a'; + return input[toknum++]; } static void @@ -1484,6 +1518,9 @@ yyerror (char const *msg) static int yylex (void) { + static int called; + if (called++) + abort (); return 0; } @@ -1547,10 +1584,13 @@ yyerror (char const *msg) static int yylex (void) { - static char const *input = "ab"; - if (*input == 'b') + static char const input[] = "ab"; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + if (input[toknum] == 'b') lookahead_value = 1; - return *input++; + return input[toknum++]; } int @@ -1636,12 +1676,14 @@ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static char const input[] = "ab"; - static char const *inputp = input; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); lvalp->dummy = 0; llocp->first_line = llocp->last_line = 2; - llocp->first_column = inputp - input + 1; + llocp->first_column = toknum + 1; llocp->last_column = llocp->first_column + 1; - return *inputp++; + return input[toknum++]; } int @@ -1672,6 +1714,7 @@ AT_DATA_GRAMMAR([glr-regr18.y], [[%glr-parser %{ + #include static void yyerror (char const *); static int yylex (); %} @@ -1703,6 +1746,9 @@ yyerror (char const *msg) static int yylex () { + static int called; + if (called++) + abort (); return 0; } @@ -1714,10 +1760,10 @@ main (void) ]]) AT_CHECK([[bison -o glr-regr18.c glr-regr18.y]], 1, [], -[glr-regr18.y:27.18-24: result type clash on merge function `merge': != -glr-regr18.y:26.18-24: previous declaration -glr-regr18.y:28.13-19: result type clash on merge function `merge': != +[glr-regr18.y:28.18-24: result type clash on merge function `merge': != glr-regr18.y:27.18-24: previous declaration +glr-regr18.y:29.13-19: result type clash on merge function `merge': != +glr-regr18.y:28.18-24: previous declaration ]) AT_CLEANUP diff --git a/tests/input.at b/tests/input.at index 7b009758..f6eb33c4 100644 --- a/tests/input.at +++ b/tests/input.at @@ -459,11 +459,14 @@ value_as_yystype (value val) static int yylex (void) { - static const char *input = "@<:@\1\2$@{@oline@__@&t@oline__\ + static char const input[] = "@<:@\1\2$@{@oline@__@&t@oline__\ #output "; /* " */ - yylval = value_as_yystype (*input); - return *input++; + static size_t toknum; + if (! (toknum < sizeof input)) + abort (); + yylval = value_as_yystype (input[toknum]); + return input[toknum++]; } static void diff --git a/tests/regression.at b/tests/regression.at index 666b99e5..40a18080 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -434,6 +434,7 @@ AT_SETUP([Token definitions]) # Bison managed, when fed with `%token 'f' "f"' to #define 'f'! AT_DATA_GRAMMAR([input.y], [%{ +#include #include void yyerror (const char *s); int yylex (void); @@ -457,6 +458,9 @@ yyerror (char const *s) int yylex (void) { + static int called; + if (called++) + abort (); return SPECIAL; } @@ -822,7 +826,8 @@ m4_define([_AT_DATA_DANCER_Y], [%{ static int yylex (AT_LALR1_CC_IF([int *], [void])); AT_LALR1_CC_IF([], -[#include +[#include +#include static void yyerror (const char *);]) %} $1 @@ -896,12 +901,14 @@ yyerror (const char *s) static int yylex (AT_LALR1_CC_IF([int *lval], [void])) [{ - static int toknum = 0; - static int tokens[] = + static int const tokens[] = { ':', -1 }; + static size_t toknum; ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[ + if (! (toknum < sizeof tokens / sizeof *tokens)) + abort (); return tokens[toknum++]; }] @@ -993,12 +1000,14 @@ yyerror (const char *s) static int yylex (AT_LALR1_CC_IF([int *lval], [void])) [{ - static int toknum = 0; - static int tokens[] = + static int const tokens[] = { 1000, '+', '+', -1 }; + static size_t toknum; ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[ + if (! (toknum < sizeof tokens / sizeof *tokens)) + abort (); return tokens[toknum++]; }] diff --git a/tests/torture.at b/tests/torture.at index 629bf976..280d79ac 100644 --- a/tests/torture.at +++ b/tests/torture.at @@ -199,10 +199,11 @@ static int yylex (void) { static int counter = 1; - if (counter > $max) - return 0; - else - return counter++; + if (counter <= $max) + return counter++; + if (counter++ != $max + 1) + abort (); + return 0; } static void @@ -331,7 +332,11 @@ yylex (void) static int return_token = 1; static int counter = 1; if (counter > $max) - return 0; + { + if (counter++ != $max + 1) + abort (); + return 0; + } if (return_token) { return_token = 0; @@ -412,6 +417,8 @@ yyerror (const char *msg) static int yylex (void) { + if (yylval < 0) + abort (); if (yylval--) return WAIT_FOR_EOF; else -- 2.45.2