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 12:01:22 +01:00
parent e1d06b5235
commit ee028dceff
4 changed files with 41 additions and 10 deletions

14
NEWS
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
THANKS
View File

@@ -83,6 +83,7 @@ Martin Mokrejs mmokrejs@natur.cuni.cz
Martin Nylin martin.nylin@linuxmail.org Martin Nylin martin.nylin@linuxmail.org
Matt Kraai kraai@alumni.cmu.edu Matt Kraai kraai@alumni.cmu.edu
Matt Rosing rosing@peakfive.com Matt Rosing rosing@peakfive.com
Michael Catanzaro mcatanzaro@gnome.org
Michael Felt mamfelt@gmail.com Michael Felt mamfelt@gmail.com
Michael Hayes m.hayes@elec.canterbury.ac.nz Michael Hayes m.hayes@elec.canterbury.ac.nz
Michael Raskin 7c6f434c@mail.ru Michael Raskin 7c6f434c@mail.ru

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

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"); }