Le 9 oct. 2013 à 15:22, Paolo Simone Gasparello <[email protected]> a écrit :
> I think I've found an issue with the lalr1.cc generator. > > The code: http://pastebin.com/6kTvLRwr > > That is a simple calculator parser. When a string that refers to an invalid > identifier is given to the parser, an assertion failure is raised. Hi Paolo, Thanks for the report! Would it be possible to have a full compilable example that triggers the error? Something I could use to try to reproduce it in the test suite, and then to check that fixes do fix :) > The assertion that fails is: > > YYASSERT (yytname_ == typeid (T).name ()); > > in the method variant::as. > > It fails because yytname_ is null, while typeid (T).name () is "double". > > It is generated the second time the local variable yylhs is destroyed in > the parse method. It seems to me that there is a double destruction of that > variable. The first destruction runs fine. It occurs in the code that > handles the syntax error: > > /*---------------------------------------------------. > | yyerrorlab -- error raised explicitly by YYERROR. | > `---------------------------------------------------*/ > yyerrorlab: > > /* Pacify compilers like GCC when the user code never invokes > YYERROR and the label yyerrorlab therefore never appears in user > code. */ > if (false) > goto yyerrorlab; > yyerror_range[1].location = yystack_[yylen - 1].location; > /* $$ was initialized before running the user action. */ > YY_SYMBOL_PRINT ("Error: discarding", yylhs); > yylhs.~stack_symbol_type(); > <----------------------------------------------------------------------- > Here the destructor is manually called, and value.yytname_ is set to > YY_NULL by variant::destroy, but typeid (T).name () is kept as "double" > /* Do not reclaim the symbols of the rule whose action triggered > this YYERROR. */ > yypop_ (yylen); > yylen = 0; > goto yyerrlab1; > > > After that, when the parse function returns 1, the yylhs local variable is > destroyed again, because it goes out of scope. Thus, during the stack > cleanup, the assertion YYASSERT (yytname_ == typeid (T).name ()); fails. I agree that while the problem seems to be that an assertion is fired, the genuine issue is that we have a double destruction. I'm not sure what the best fix would be, but it seems that we should have an "empty" value for yylhs. I'd like to toy with a real example, if possible. Thanks in advance!
