mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 09:13:04 +00:00
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.
This commit is contained in:
@@ -828,7 +828,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
|||||||
/* Do not reclaim the symbols of the rule which action triggered
|
/* Do not reclaim the symbols of the rule which action triggered
|
||||||
this YYABORT or YYACCEPT. */
|
this YYABORT or YYACCEPT. */
|
||||||
yypop_ (yylen);
|
yypop_ (yylen);
|
||||||
while (yystate_stack_.height () != 1)
|
while (1 < yystate_stack_.height ())
|
||||||
{
|
{
|
||||||
yydestruct_ ("Cleanup: popping",
|
yydestruct_ ("Cleanup: popping",
|
||||||
yystos_[yystate_stack_[0]],
|
yystos_[yystate_stack_[0]],
|
||||||
@@ -852,7 +852,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
|
|||||||
&yylloc);
|
&yylloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (yystate_stack_.height () != 1)
|
while (1 < yystate_stack_.height ())
|
||||||
{
|
{
|
||||||
yydestruct_ ("Cleanup: popping",
|
yydestruct_ ("Cleanup: popping",
|
||||||
yystos_[yystate_stack_[0]],
|
yystos_[yystate_stack_[0]],
|
||||||
|
|||||||
24
tests/c++.at
24
tests/c++.at
@@ -226,6 +226,7 @@ AT_DATA_GRAMMAR([[input.yy]],
|
|||||||
%code
|
%code
|
||||||
{
|
{
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring> // strchr
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
int yylex (yy::parser::semantic_type *);
|
int yylex (yy::parser::semantic_type *);
|
||||||
size_t Object::counter = 0;
|
size_t Object::counter = 0;
|
||||||
@@ -237,6 +238,12 @@ AT_DATA_GRAMMAR([[input.yy]],
|
|||||||
Object* obj;
|
Object* obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%initial-action
|
||||||
|
{
|
||||||
|
if (strchr (input, 'i'))
|
||||||
|
throw std::runtime_error ("initial-action");
|
||||||
|
}
|
||||||
|
|
||||||
%destructor { delete $$; } <obj>;
|
%destructor { delete $$; } <obj>;
|
||||||
%printer { yyo << "counter == " << $$->counter; } <obj>;
|
%printer { yyo << "counter == " << $$->counter; } <obj>;
|
||||||
|
|
||||||
@@ -260,7 +267,7 @@ item:
|
|||||||
| 's'
|
| 's'
|
||||||
{
|
{
|
||||||
std::swap ($$, $1);
|
std::swap ($$, $1);
|
||||||
throw std::runtime_error ("invalid expression");
|
throw std::runtime_error ("reduction");
|
||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@@ -268,11 +275,14 @@ item:
|
|||||||
int
|
int
|
||||||
yylex (yy::parser::semantic_type *lvalp)
|
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++)
|
switch (int res = *input++)
|
||||||
{
|
{
|
||||||
case 'l':
|
case 'l':
|
||||||
throw std::runtime_error ("invalid character");
|
throw std::runtime_error ("yylex");
|
||||||
default:
|
default:
|
||||||
lvalp->obj = new Object;
|
lvalp->obj = new Object;
|
||||||
// Fall through.
|
// Fall through.
|
||||||
@@ -312,11 +322,15 @@ AT_BISON_CHECK([[-o input.cc input.yy]])
|
|||||||
AT_COMPILE_CXX([[input]])
|
AT_COMPILE_CXX([[input]])
|
||||||
|
|
||||||
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
|
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
|
||||||
[[exception caught: invalid expression
|
[[exception caught: reduction
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_PARSER_CHECK([[./input aaaal]], [[2]], [[]],
|
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
|
AT_BISON_OPTION_POPDEFS
|
||||||
|
|||||||
Reference in New Issue
Block a user