From a26424642b1de2c5e237cd69a54f12b2f430321f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 25 Sep 2012 11:17:55 +0200 Subject: [PATCH] lalr1.cc: check (and fix) %initial-action exception safety * data/lalr1.cc: Check size > 1, rather than size != 1, when cleaning the stack, as at the beginning, size is 0. * tests/c++.at (Exception safety): Check exception safety in %initial-action. --- data/lalr1.cc | 4 ++-- tests/c++.at | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/data/lalr1.cc b/data/lalr1.cc index fe23b3e..2ec1d0d 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -828,7 +828,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ yypop_ (yylen); - while (yystate_stack_.height () != 1) + while (1 < yystate_stack_.height ()) { yydestruct_ ("Cleanup: popping", yystos_[yystate_stack_[0]], @@ -852,7 +852,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; &yylloc); } - while (yystate_stack_.height () != 1) + while (1 < yystate_stack_.height ()) { yydestruct_ ("Cleanup: popping", yystos_[yystate_stack_[0]], diff --git a/tests/c++.at b/tests/c++.at index 304a72d..e4a7911 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -226,6 +226,7 @@ AT_DATA_GRAMMAR([[input.yy]], %code { #include + #include // strchr #include int yylex (yy::parser::semantic_type *); size_t Object::counter = 0; @@ -237,6 +238,12 @@ AT_DATA_GRAMMAR([[input.yy]], Object* obj; } +%initial-action +{ + if (strchr (input, 'i')) + throw std::runtime_error ("initial-action"); +} + %destructor { delete $$; } ; %printer { yyo << "counter == " << $$->counter; } ; @@ -260,7 +267,7 @@ item: | 's' { std::swap ($$, $1); - throw std::runtime_error ("invalid expression"); + throw std::runtime_error ("reduction"); } %% @@ -268,11 +275,14 @@ item: int yylex (yy::parser::semantic_type *lvalp) { - // 'l': lexical exception, 's': syntactic exception. + // 'a': no error. + // 'i': initial action throws. + // 'l': yylex throws. + // 's': reduction throws. switch (int res = *input++) { case 'l': - throw std::runtime_error ("invalid character"); + throw std::runtime_error ("yylex"); default: lvalp->obj = new Object; // Fall through. @@ -312,11 +322,15 @@ AT_BISON_CHECK([[-o input.cc input.yy]]) AT_COMPILE_CXX([[input]]) AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]], -[[exception caught: invalid expression +[[exception caught: reduction ]]) AT_PARSER_CHECK([[./input aaaal]], [[2]], [[]], -[[exception caught: invalid character +[[exception caught: yylex +]]) + +AT_PARSER_CHECK([[./input i]], [[2]], [[]], +[[exception caught: initial-action ]]) AT_BISON_OPTION_POPDEFS -- 2.7.4