c++: fix the use of destructors when variants are enabled

When using variants, destructors generate invalid code.
<http://lists.gnu.org/archive/html/bug-bison/2014-09/msg00005.html>
Reported by Michael Catanzaro.

* data/c++.m4 (~basic_symbol): b4_symbol_foreach works on yysym:
define it.
* tests/c++.at (Variants): Check it.
This commit is contained in:
Akim Demaille
2015-01-09 13:54:58 +01:00
parent e1d06b5235
commit ee028dceff
4 changed files with 41 additions and 10 deletions
+9 -5
View File
@@ -4,19 +4,23 @@ GNU Bison NEWS
** Bug fixes ** Bug fixes
*** Named %union support *** C++ with Variants (lalr1.cc)
Problems with %destructor and '%define parse.assert' have been fixed.
*** Named %union support (yacc.c, glr.c)
Bison 3.0 introduced a regression on named %union such as Bison 3.0 introduced a regression on named %union such as
%union foo { int ival; }; %union foo { int ival; };
The possibility to use a name was introduced ``for Yacc compatibility''. The possibility to use a name was introduced "for Yacc compatibility".
It is however not required by POSIX Yacc, and its usefulness is not clear. It is however not required by POSIX Yacc, and its usefulness is not clear.
*** %define api.value.type union with %defines *** %define api.value.type union with %defines (yacc.c, glr.c)
The yacc.c and glr.c parsers were broken when %defines was used The C parsers were broken when %defines was used together with "%define
together with "%define api.value.type union". api.value.type union".
*** Redeclarations are reported in proper order *** Redeclarations are reported in proper order
+1
View File
@@ -83,6 +83,7 @@ Martin Mokrejs [email protected]
Martin Nylin [email protected] Martin Nylin [email protected]
Matt Kraai [email protected] Matt Kraai [email protected]
Matt Rosing [email protected] Matt Rosing [email protected]
Michael Catanzaro [email protected]
Michael Felt [email protected] Michael Felt [email protected]
Michael Hayes [email protected] Michael Hayes [email protected]
Michael Raskin [email protected] Michael Raskin [email protected]
+1
View File
@@ -346,6 +346,7 @@ m4_define([b4_public_types_define],
{]b4_variant_if([[ {]b4_variant_if([[
// User destructor. // User destructor.
symbol_number_type yytype = this->type_get (); symbol_number_type yytype = this->type_get ();
basic_symbol<Base>& yysym = *this;
switch (yytype) switch (yytype)
{ {
]b4_symbol_foreach([b4_symbol_destructor])dnl ]b4_symbol_foreach([b4_symbol_destructor])dnl
+30 -5
View File
@@ -252,10 +252,12 @@ typedef std::list<std::string> strings_type;
// Using the template type to exercize its parsing. // Using the template type to exercize its parsing.
// Starting with :: to ensure we don't output "<::" which starts by the // Starting with :: to ensure we don't output "<::" which starts by the
// digraph for the left square bracket. // digraph for the left square bracket.
%type <::std::list<std::string>> list result; %type <::std::list<std::string>> list;
%printer { yyo << $$; } %printer { yyo << $$; }
<int> <::std::string> <::std::list<std::string>>; <int> <::std::string> <::std::list<std::string>>;
%destructor { std::cerr << "Destroy: " << $$ << '\n'; } <*>;
%destructor { std::cerr << "Destroy: \"" << $$ << "\"\n"; } <::std::string>;
%% %%
result: result:
@@ -336,8 +338,31 @@ namespace yy
AT_FULL_COMPILE([list]) AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0, AT_PARSER_CHECK([./list], 0,
[(0, 1, 2, 4, 6) [[(0, 1, 2, 4, 6)
]) ]],
[[Destroy: ""
Destroy: "0"
Destroy: (0)
Destroy: 1
Destroy: "1"
Destroy: ()
Destroy: ""
Destroy: "2"
Destroy: ()
Destroy: ""
Destroy: 3
Destroy: ()
Destroy: ""
Destroy: "4"
Destroy: ()
Destroy: ()
Destroy: 5
Destroy: ()
Destroy: ""
Destroy: "6"
Destroy: ()
Destroy: (0, 1, 2, 4, 6)
]])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
AT_CLEANUP AT_CLEANUP
@@ -826,10 +851,10 @@ list:
item: item:
'a' { $$ = $][1; } 'a' { $$ = $][1; }
| 'e' { YYUSE ($$); YYUSE($][1); error ("syntax error"); } | 'e' { YYUSE ($$); YYUSE ($][1); error ("syntax error"); }
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and // Not just 'E', otherwise we reduce when 'E' is the lookahead, and
// then the stack is emptied, defeating the point of the test. // then the stack is emptied, defeating the point of the test.
| 'E' 'a' { YYUSE($][1); $$ = $][2; } | 'E' 'a' { YYUSE ($][1); $$ = $][2; }
| 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; } | 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; }
| 'p' { $$ = $][1; } | 'p' { $$ = $][1; }
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); } | 's' { $$ = $][1; throw std::runtime_error ("reduction"); }