When variant are enabled, the yylhs variable (the left-hand side of
the rule being reduced, i.e. $$ and @$) is explicitly destroyed when
YYERROR is called. This is because before running the user code, $$
is initialized, so that the user can properly use it.
However, when quitting yyparse, yylhs is also reclaimed by the C++
compiler: the variable goes out of scope.
Instead of trying to be too smart, let the compiler do its job: reduce
the scope of yylhs to exactly the reduction. This way, whatever the
type of scope exit (regular, exception, return, goto...) this variable
will be properly reclaimed.
Reported by Paolo Simone Gasparello.
<http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00003.html>
* data/lalr1.cc (yyparse): Reduce the scope of yylhs.
* tests/c++.at: We now pass this test.
+ /// Length of the RHS of the rule being reduced.
int yylen = 0;
// Error handling.
int yylen = 0;
// Error handling.
/// The locations where the error started and ended.
stack_symbol_type yyerror_range[3];]])[
/// The locations where the error started and ended.
stack_symbol_type yyerror_range[3];]])[
- /// $$ and @@$.
- stack_symbol_type yylhs;
-
/// The return value of parse ().
int yyresult;
/// The return value of parse ().
int yyresult;
`-----------------------------*/
yyreduce:
yylen = yyr2_[yyn];
`-----------------------------*/
yyreduce:
yylen = yyr2_[yyn];
+ {
+ stack_symbol_type yylhs;
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
/* Variants are always initialized to an empty instance of the
correct type. The default $$=$1 action is NOT applied when using
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
/* Variants are always initialized to an empty instance of the
correct type. The default $$=$1 action is NOT applied when using
// Shift the result of the reduction.
yypush_ (YY_NULLPTR, yylhs);
// Shift the result of the reduction.
yypush_ (YY_NULLPTR, yylhs);
goto yynewstate;
/*--------------------------------------.
goto yynewstate;
/*--------------------------------------.
code. */
if (false)
goto yyerrorlab;]b4_locations_if([[
code. */
if (false)
goto yyerrorlab;]b4_locations_if([[
- yyerror_range[1].location = yystack_[yylen - 1].location;]])b4_variant_if([[
- /* $$ was initialized before running the user action. */
- YY_SYMBOL_PRINT ("Error: discarding", yylhs);
- yylhs.~stack_symbol_type();]])[
+ yyerror_range[1].location = yystack_[yylen - 1].location;]])[
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
yypop_ (yylen);
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
yypop_ (yylen);
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
-m4_if([$1], [], [],
- [m4_if([$2], [without], [AT_XFAIL_IF([true])])])
-
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
AT_DATA_GRAMMAR([[input.yy]],
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
AT_DATA_GRAMMAR([[input.yy]],