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
*** 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
%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.
*** %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
together with "%define api.value.type union".
The C parsers were broken when %defines was used together with "%define
api.value.type union".
*** 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
Matt Kraai kraai@alumni.cmu.edu
Matt Rosing rosing@peakfive.com
Michael Catanzaro mcatanzaro@gnome.org
Michael Felt mamfelt@gmail.com
Michael Hayes m.hayes@elec.canterbury.ac.nz
Michael Raskin 7c6f434c@mail.ru

View File

@@ -346,6 +346,7 @@ m4_define([b4_public_types_define],
{]b4_variant_if([[
// User destructor.
symbol_number_type yytype = this->type_get ();
basic_symbol<Base>& yysym = *this;
switch (yytype)
{
]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.
// Starting with :: to ensure we don't output "<::" which starts by the
// digraph for the left square bracket.
%type <::std::list<std::string>> list result;
%type <::std::list<std::string>> list;
%printer { yyo << $$; }
<int> <::std::string> <::std::list<std::string>>;
%destructor { std::cerr << "Destroy: " << $$ << '\n'; } <*>;
%destructor { std::cerr << "Destroy: \"" << $$ << "\"\n"; } <::std::string>;
%%
result:
@@ -336,8 +338,31 @@ namespace yy
AT_FULL_COMPILE([list])
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_CLEANUP
@@ -826,10 +851,10 @@ list:
item:
'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
// 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; }
| 'p' { $$ = $][1; }
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); }