From 7e1fabbeae9accb48611457f550286f1934ef533 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 20 Sep 2012 16:59:29 +0200 Subject: [PATCH] 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. --- THANKS | 1 + data/lalr1.cc | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/THANKS b/THANKS index f742e8f..185097f 100644 --- a/THANKS +++ b/THANKS @@ -80,6 +80,7 @@ Nicolas Tisserand nicolas.tisserand@epita.fr Noah Friedman friedman@gnu.org Odd Arild Olsen oao@fibula.no Oleg Smolsky oleg.smolsky@pacific-simulators.co.nz +Oleksii Taran oleksii.taran@gmail.com Paolo Bonzini bonzini@gnu.org Pascal Bart pascal.bart@epita.fr Paul Eggert eggert@cs.ucla.edu diff --git a/data/lalr1.cc b/data/lalr1.cc index 846aea1..fe23b3e 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -533,6 +533,10 @@ do { \ 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; ]m4_ifdef([b4_initial_action], [ @@ -573,14 +577,13 @@ b4_dollar_popdef])[]dnl /* Read a lookahead token. */ if (yychar == yyempty_) { - YYCDEBUG << "Reading a token: "; - yychar = ]b4_c_function_call([yylex], [int], - [b4_api_PREFIX[STYPE*], [&yylval]][]dnl + YYCDEBUG << "Reading a token: "; + yychar = ]b4_c_function_call([yylex], [int], + [b4_api_PREFIX[STYPE*], [&yylval]][]dnl b4_locations_if([, [[location*], [&yylloc]]])dnl m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } - /* Convert token to internal form. */ if (yychar <= yyeof_) { @@ -651,17 +654,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; else yyval = yysemantic_stack_[0]; + // Compute the default @@$. { slice slice (yylocation_stack_, yylen); YYLLOC_DEFAULT (yyloc, slice, yylen); } + + // Perform the reduction. YY_REDUCE_PRINT (yyn); switch (yyn) { - ]b4_user_actions[ - default: - break; + ]b4_user_actions[ + default: + break; } + /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. @@ -831,6 +838,30 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } 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. -- 2.7.4