From 5c77412162fbdd2187cb384e55d1088b46a5c56d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 15 Nov 2013 10:08:31 +0100 Subject: lalr1.cc: fix the support of YYERROR with variants 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. * data/lalr1.cc (yyparse): Reduce the scope of yylhs. * tests/c++.at: We now pass this test. --- data/lalr1.cc | 12 +++++------- tests/c++.at | 3 --- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/data/lalr1.cc b/data/lalr1.cc index d3d063ab..61dc6663 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -700,6 +700,7 @@ m4_if(b4_prefix, [yy], [], // State. int yyn; + /// Length of the RHS of the rule being reduced. int yylen = 0; // Error handling. @@ -712,9 +713,6 @@ m4_if(b4_prefix, [yy], [], /// 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; @@ -815,6 +813,8 @@ b4_dollar_popdef])[]dnl `-----------------------------*/ 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 @@ -861,6 +861,7 @@ b4_dollar_popdef])[]dnl // Shift the result of the reduction. yypush_ (YY_NULLPTR, yylhs); + } goto yynewstate; /*--------------------------------------. @@ -907,10 +908,7 @@ b4_dollar_popdef])[]dnl 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); diff --git a/tests/c++.at b/tests/c++.at index 355e6247..5b3df02b 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -658,9 +658,6 @@ m4_pushdef([AT_TEST], 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]], -- cgit v1.2.1