mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
lalr1.cc: fix exception safety
lalr1.cc does not reclaim its memory when ended by an exception. Reported by Oleksii Taran: http://lists.gnu.org/archive/html/help-bison/2012-09/msg00000.html * data/lalr1.cc (yyparse): Protect the whole yyparse by a try-catch block that cleans the stack and the lookahead.
This commit is contained in:
1
THANKS
1
THANKS
@@ -80,6 +80,7 @@ Nicolas Tisserand nicolas.tisserand@epita.fr
|
|||||||
Noah Friedman friedman@gnu.org
|
Noah Friedman friedman@gnu.org
|
||||||
Odd Arild Olsen oao@fibula.no
|
Odd Arild Olsen oao@fibula.no
|
||||||
Oleg Smolsky oleg.smolsky@pacific-simulators.co.nz
|
Oleg Smolsky oleg.smolsky@pacific-simulators.co.nz
|
||||||
|
Oleksii Taran oleksii.taran@gmail.com
|
||||||
Paolo Bonzini bonzini@gnu.org
|
Paolo Bonzini bonzini@gnu.org
|
||||||
Pascal Bart pascal.bart@epita.fr
|
Pascal Bart pascal.bart@epita.fr
|
||||||
Paul Eggert eggert@cs.ucla.edu
|
Paul Eggert eggert@cs.ucla.edu
|
||||||
|
|||||||
@@ -533,6 +533,10 @@ do { \
|
|||||||
|
|
||||||
int yyresult;
|
int yyresult;
|
||||||
|
|
||||||
|
// FIXME: This shoud be completely indented. It is not yet to
|
||||||
|
// avoid gratuitous conflicts when merging into the master branch.
|
||||||
|
try
|
||||||
|
{
|
||||||
YYCDEBUG << "Starting parse" << std::endl;
|
YYCDEBUG << "Starting parse" << std::endl;
|
||||||
|
|
||||||
]m4_ifdef([b4_initial_action], [
|
]m4_ifdef([b4_initial_action], [
|
||||||
@@ -573,14 +577,13 @@ b4_dollar_popdef])[]dnl
|
|||||||
/* Read a lookahead token. */
|
/* Read a lookahead token. */
|
||||||
if (yychar == yyempty_)
|
if (yychar == yyempty_)
|
||||||
{
|
{
|
||||||
YYCDEBUG << "Reading a token: ";
|
YYCDEBUG << "Reading a token: ";
|
||||||
yychar = ]b4_c_function_call([yylex], [int],
|
yychar = ]b4_c_function_call([yylex], [int],
|
||||||
[b4_api_PREFIX[STYPE*], [&yylval]][]dnl
|
[b4_api_PREFIX[STYPE*], [&yylval]][]dnl
|
||||||
b4_locations_if([, [[location*], [&yylloc]]])dnl
|
b4_locations_if([, [[location*], [&yylloc]]])dnl
|
||||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert token to internal form. */
|
/* Convert token to internal form. */
|
||||||
if (yychar <= yyeof_)
|
if (yychar <= yyeof_)
|
||||||
{
|
{
|
||||||
@@ -651,17 +654,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
|||||||
else
|
else
|
||||||
yyval = yysemantic_stack_[0];
|
yyval = yysemantic_stack_[0];
|
||||||
|
|
||||||
|
// Compute the default @@$.
|
||||||
{
|
{
|
||||||
slice<location_type, location_stack_type> slice (yylocation_stack_, yylen);
|
slice<location_type, location_stack_type> slice (yylocation_stack_, yylen);
|
||||||
YYLLOC_DEFAULT (yyloc, slice, yylen);
|
YYLLOC_DEFAULT (yyloc, slice, yylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform the reduction.
|
||||||
YY_REDUCE_PRINT (yyn);
|
YY_REDUCE_PRINT (yyn);
|
||||||
switch (yyn)
|
switch (yyn)
|
||||||
{
|
{
|
||||||
]b4_user_actions[
|
]b4_user_actions[
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User semantic actions sometimes alter yychar, and that requires
|
/* User semantic actions sometimes alter yychar, and that requires
|
||||||
that yytoken be updated with the new translation. We take the
|
that yytoken be updated with the new translation. We take the
|
||||||
approach of translating immediately before every use of yytoken.
|
approach of translating immediately before every use of yytoken.
|
||||||
@@ -831,6 +838,30 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
|||||||
}
|
}
|
||||||
|
|
||||||
return yyresult;
|
return yyresult;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
YYCDEBUG << "Exception caught" << std::endl;
|
||||||
|
if (yychar != yyempty_)
|
||||||
|
{
|
||||||
|
/* Make sure we have latest lookahead translation. See
|
||||||
|
comments at user semantic actions for why this is
|
||||||
|
necessary. */
|
||||||
|
yytoken = yytranslate_ (yychar);
|
||||||
|
yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval,
|
||||||
|
&yylloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (yystate_stack_.height () != 1)
|
||||||
|
{
|
||||||
|
yydestruct_ ("Cleanup: popping",
|
||||||
|
yystos_[yystate_stack_[0]],
|
||||||
|
&yysemantic_stack_[0],
|
||||||
|
&yylocation_stack_[0]);
|
||||||
|
yypop_ ();
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate an error message.
|
// Generate an error message.
|
||||||
|
|||||||
Reference in New Issue
Block a user