summaryrefslogtreecommitdiff
path: root/tests/conflicts.at
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2019-11-27 08:24:58 +0100
committerAkim Demaille <akim.demaille@gmail.com>2019-11-29 18:21:43 +0100
commit2f7097d1b1414fe8ac28e128c1e12b440f54b2f2 (patch)
tree66bbf3e037803ee23689af88a1e11de51ae8c60b /tests/conflicts.at
parent28369ecb5d4184f4bed8cccd9e8e018a3d985c75 (diff)
downloadbison-2f7097d1b1414fe8ac28e128c1e12b440f54b2f2.tar.gz
yacc.c, glr.c: fix crash when reporting errors in consistent states
The current code for yysyntax_error for %define parse.error verbose is fishy (given that YYEMPTY is -2, invalid argument for yytname[]): static int yysyntax_error ([...]) { YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); [...] if (yytoken != YYEMPTY) A nearby comment reports The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". So it _is_ possible to call yysyntax_error with yytoken == YYEMPTY, albeit quite difficult when meaning to, so virtually impossible by accident (after all, there was never a bug report about this). I failed to produce a test case, but Joel E. Denny provided me with one (added to the test suite below). The yacc.c skeleton fails on this, and once fixed dies on a second problem. The glr.c skeleton was also dying, but immediately of this second problem. Indeed we were not allocating space for the error message's final \0. This was hidden by the fact that we only had error messages with at least an unexpected token displayed, so with at least one "%s" in the format string, whose size (2) was included (incorrectly) in the final size of the message (where the %s have been replaced by the actual content). * data/skeletons/glr.c, data/skeletons/yacc.c (yysyntax_error): Do not invoke yytnamerr on YYEMPTY. Clarify the computation of the length of the _final_ error message, with the NUL terminator but without the '%s's. * tests/conflicts.at (Syntax error in consistent error state): New, contributed by Joel E. Denny.
Diffstat (limited to 'tests/conflicts.at')
-rw-r--r--tests/conflicts.at60
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/conflicts.at b/tests/conflicts.at
index e857bf20..92050fbe 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1019,6 +1019,66 @@ input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
AT_CLEANUP
+## ---------------------------------------- ##
+## Syntax error in consistent error state. ##
+## ---------------------------------------- ##
+
+# AT_TEST(SKELETON-NAME)
+# ----------------------
+# Make sure yysyntax_error does nothing silly when called on yytoken
+# == YYEMPTY.
+
+m4_pushdef([AT_TEST],
+[AT_SETUP([Syntax error in consistent error state: $1])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"])
+
+AT_DATA_GRAMMAR([input.y],
+[[%define parse.error verbose
+%skeleton "$1"
+%%
+%nonassoc 'a';
+
+start: 'a' consistent-error-on-a-a 'a';
+
+consistent-error-on-a-a:
+ 'a' default-reduction
+ | 'a' default-reduction 'a'
+ ;
+
+default-reduction: %empty;
+
+%code {
+ #include <stdio.h>
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
+};
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE("aa")[
+]AT_MAIN_DEFINE[
+]])
+
+AT_BISON_CHECK([-o input.AT_LANG_EXT input.y], 0, [],
+[[input.y:17.5-25: warning: rule useless in parser due to conflicts [-Wother]
+input.y:18.5-29: warning: rule useless in parser due to conflicts [-Wother]
+]])
+AT_LANG_COMPILE([input])
+AT_PARSER_CHECK([[input]], 1, [],
+[[syntax error
+]])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+])
+
+## FIXME: test Java and D.
+m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
+
+m4_popdef([AT_TEST])
+
+
+
## -------------------------------- ##
## Defaulted Conflicted Reduction. ##
## -------------------------------- ##