mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
tests: check that using variants is exception safe
* tests/local.at: (Slightly) improve the regexp by escaping '.' when it denotes a point. (AT_VARIANT_IF): New. * tests/c++.at (Exception Safety): Run it for variants too.
This commit is contained in:
85
tests/c++.at
85
tests/c++.at
@@ -589,15 +589,19 @@ AT_CLEANUP
|
||||
## Exception safety. ##
|
||||
## ------------------ ##
|
||||
|
||||
AT_SETUP([[Exception safety]])
|
||||
# AT_TEST([BISON-DIRECTIVES])
|
||||
# ---------------------------
|
||||
# Check that no object is leaked when exceptions are thrown.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([[Exception safety $1]])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.yy]],
|
||||
[[%skeleton "lalr1.cc"
|
||||
%debug
|
||||
%error-verbose
|
||||
|
||||
$1
|
||||
%code requires
|
||||
{
|
||||
#include <cassert>
|
||||
@@ -648,6 +652,13 @@ AT_DATA_GRAMMAR([[input.yy]],
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
instances.remove(this);
|
||||
@@ -666,17 +677,21 @@ AT_DATA_GRAMMAR([[input.yy]],
|
||||
static char const *input;
|
||||
}
|
||||
|
||||
]AT_VARIANT_IF([[
|
||||
%printer
|
||||
{
|
||||
yyo << &$$ << " '" << $$.val << '\'';
|
||||
if ($$.val == 'p')
|
||||
throw std::runtime_error ("printer");
|
||||
} <Object>;
|
||||
|
||||
%token <Object> 'a' 'E' 'e' 'p' 'R' 's' 'T'
|
||||
%type <Object> list item
|
||||
]], [[
|
||||
%union
|
||||
{
|
||||
Object *obj;
|
||||
}
|
||||
|
||||
%initial-action
|
||||
{
|
||||
if (strchr (input, 'i'))
|
||||
throw std::runtime_error ("initial-action");
|
||||
}
|
||||
|
||||
%destructor { delete $$; } <obj>;
|
||||
%printer
|
||||
{
|
||||
@@ -687,27 +702,35 @@ AT_DATA_GRAMMAR([[input.yy]],
|
||||
|
||||
%token <obj> 'a' 'E' 'e' 'p' 'R' 's' 'T'
|
||||
%type <obj> list item
|
||||
]])[
|
||||
|
||||
%initial-action
|
||||
{
|
||||
if (strchr (input, 'i'))
|
||||
throw std::runtime_error ("initial-action");
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
start: list { delete $1; };
|
||||
start: list {]AT_VARIANT_IF([], [ delete $][1]; )[};
|
||||
|
||||
list:
|
||||
item { $$ = $1; }
|
||||
| item list { $$ = $1; delete $2; } // Right recursion to load the stack.
|
||||
item { $][$ = $][1; }
|
||||
// Right recursion to load the stack.
|
||||
| item list { $][$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
|
||||
;
|
||||
|
||||
item:
|
||||
'a' { $$ = $1; }
|
||||
| 'e' { YYUSE ($$); YYUSE($1); error ("syntax error"); }
|
||||
'a' { $$][ = $][1; }
|
||||
| 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
|
||||
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
|
||||
// then the stack is emptied, defeating the point of the test.
|
||||
| 'E' 'a' { YYUSE($1); $$ = $2; }
|
||||
| 'R' { $$ = YY_NULL; delete $1; YYERROR; }
|
||||
| 'p' { $$ = $1; }
|
||||
| 's' { $$ = $1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { $$ = YY_NULL; delete $1; YYABORT; }
|
||||
| error { $$ = YY_NULL; yyerrok; }
|
||||
| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
|
||||
| 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
|
||||
| 'p' { $][$ = $][1; }
|
||||
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
|
||||
| error { $][$ = YY_NULL; yyerrok; }
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -724,13 +747,13 @@ yylex (yy::parser::semantic_type *lvalp)
|
||||
// 'T': call YYABORT in the action
|
||||
switch (int res = *input++)
|
||||
{
|
||||
case 'l':
|
||||
throw std::runtime_error ("yylex");
|
||||
default:
|
||||
lvalp->obj = new Object (res);
|
||||
// Fall through.
|
||||
case 0:
|
||||
return res;
|
||||
case 'l':
|
||||
throw std::runtime_error ("yylex");
|
||||
default:
|
||||
lvalp]AT_VARIANT_IF([->build (res)], [->obj = new Object (res)])[;
|
||||
// Fall through.
|
||||
case 0:
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,6 +838,12 @@ AT_PARSER_CHECK([[./input aaaaR]], [[0]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
AT_TEST
|
||||
AT_TEST([%define api.value.type variant])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
## ------------------------------------ ##
|
||||
## C++ GLR parser identifier shadowing ##
|
||||
|
||||
@@ -186,10 +186,12 @@ m4_pushdef([AT_NAME_PREFIX],
|
||||
[m4_bregexp([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) "\([^""]*\)"], [\3])],
|
||||
[yy])])
|
||||
m4_pushdef([AT_TOKEN_CTOR_IF],
|
||||
[m4_bmatch([$3], [%define api.token.constructor], [$1], [$2])])
|
||||
[m4_bmatch([$3], [%define api\.token\.constructor], [$1], [$2])])
|
||||
m4_pushdef([AT_TOKEN_PREFIX],
|
||||
[m4_bmatch([$3], [%define api.token.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api.token.prefix "\(.*\)"], [\1])])])
|
||||
[m4_bmatch([$3], [%define api\.token\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.token\.prefix "\(.*\)"], [\1])])])
|
||||
m4_pushdef([AT_VARIANT_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type "?variant"?], [$1], [$2])])
|
||||
m4_pushdef([AT_API_prefix],
|
||||
[m4_bmatch([$3], [%define api\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
|
||||
@@ -203,7 +205,7 @@ m4_pushdef([AT_API_PREFIX],
|
||||
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
|
||||
[AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3],
|
||||
m4_quote(m4_join([\|],
|
||||
[%define api.pure "?full"?],
|
||||
[%define api\.pure "?full"?],
|
||||
[%glr-parser],
|
||||
[%parse-param],
|
||||
[%skeleton "?glr.c"?])),
|
||||
@@ -288,6 +290,7 @@ m4_popdef([AT_YYERROR_SEES_LOC_IF])
|
||||
m4_popdef([AT_YYERROR_ARG_LOC_IF])
|
||||
m4_popdef([AT_API_PREFIX])
|
||||
m4_popdef([AT_API_prefix])
|
||||
m4_popdef([AT_VARIANT_IF])
|
||||
m4_popdef([AT_TOKEN_PREFIX])
|
||||
m4_popdef([AT_TOKEN_CTOR_IF])
|
||||
m4_popdef([AT_NAME_PREFIX])
|
||||
|
||||
Reference in New Issue
Block a user