on 2005-04-28, at 22:46:21 -0700, Paul Eggert wrote:
> Marcus Holland-Moritz <[EMAIL PROTECTED]> writes:
>
> > When the parser detects a stack overflow, it should call
> > the cleanup actions defined via %destructor for all symbols
> > on the stack (and the symbol causing the overflow) before
> > it returns.
>
> Yes, that sounds right. Can you write and test a patch to data/yacc.c
> that does that? Presumably it would be some code executed just after
> the "parser stack overflow" message, that would call yydestruct.
What about the attached patch against the CVS version of bison?
All tests still pass, and I've added a test to tests/actions.at that
forces a stack overflow and checks that all symbols are freed.
If especially the test part looks kludgy, it's probably because I've
never used m4/autotest before...
Marcus
--- bison/data/yacc.c 2005-04-25 05:14:22.000000000 +0200
+++ bison-mhx/data/yacc.c 2005-04-30 12:26:31.000000000 +0200
@@ -1316,6 +1316,18 @@
`----------------------------------------------*/
yyoverflowlab:
yyerror (]b4_yyerror_args[_("parser stack overflow"));
+ yydestruct (_("Error: discarding lookahead"),
+ yytoken, &yylval]b4_location_if([, &yylloc])[);
+ for (;;)
+ {
+]b4_location_if([[ yyerror_range[0] = *yylsp;]])[
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ break;
+ yydestruct (_("Error: popping"),
+ yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
+ }
+ yychar = YYEMPTY;
yyresult = 2;
/* Fall through. */
#endif
--- bison/tests/actions.at 2004-12-20 14:56:38.000000000 +0100
+++ bison-mhx/tests/actions.at 2005-04-30 19:55:20.000000000 +0200
@@ -174,6 +174,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+
+#define YYINITDEPTH 10
+#define YYMAXDEPTH 10
]AT_LALR1_CC_IF(
[#define RANGE(Location) (Location).begin.line, (Location).end.line],
[#define RANGE(Location) (Location).first_line, (Location).last_line])
@@ -442,6 +445,58 @@
Parsing FAILED.
]])
+# Check destruction upon stack overflow
+# -------------------------------------
+# Upon stack overflow, all symbols on the stack should be destroyed.
+# Only check for yacc.c.
+AT_YACC_IF([
+AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 1,
+[[sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+200-209: parser stack overflow
+Freeing nterm thing ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Parsing FAILED.
+]])
+])
+
])