bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug Report Bison 3.0.4: parser crash when throwing syntax_error in C


From: Akim Demaille
Subject: Re: Bug Report Bison 3.0.4: parser crash when throwing syntax_error in C++ parser with locations from mid-rule actions
Date: Fri, 17 Aug 2018 20:03:11 +0200

Hi Denis!

> Le 25 mars 2016 à 19:37, Denis T <address@hidden> a écrit :
> 
> Hi,
> 
> I've found out that Bison 3.0.4 parser crashes when you attempt to throw 
> syntax_error from any mid-rule action of C++ parser, which uses location 
> tracking. Here's a simple example:
> 
> %code provides {
> int yylex(yy::parser::semantic_type* type, const yy::parser::location_type* 
> loc);
> }
> 
> %require "3.0.4"
> %language "C++"
> %skeleton "lalr1.cc"
> %locations
> %define api.value.type {int}
> 
> %%
> 
> start:
>    '1' '2' '3' { throw syntax_error(@1, "Test"); } '4' '5' '6' { $$ = 0; }
> ;
> 
> %%
> 
> void yy::parser::error(const yy::parser::location_type& loc, const 
> std::string& message)
> {
>    std::cout << message << std::endl;
> }
> 
> int yylex(yy::parser::semantic_type* type, const yy::parser::location_type* 
> loc)
> {
>    static int start = '0';
>    return ++start;
> }
> 
> int main()
> {
>    yy::parser().parse();
> }
> 
> 
> The crash occurs in yyerrorlab, when trying to do something with locations, 
> in the following autogenerated line:
> yyerror_range[1].location = yystack_[yylen - 1].location; // <- crash, as 
> yylen = 0 here

Good catch.  For the record, Bison 3.0.5 has a fix for this.

I’m ashamed to report that 3.0.5 was released recently (May 27th 2018), but the 
fix was sitting in git long before.

commit 476c1cca5945eeef3493cfc6ef06ed6d0972d787
Author: Akim Demaille <address@hidden>
Date:   Tue Aug 11 13:48:57 2015 +0200

    lalr1, yacc: use the default location as initial error location
    
    Currently lalr1.cc makes an out-of-bound access when trying to read @1
    in rules with an empty rhs (i.e., when there is no @1) that raises an
    error (YYERROR).
    
    glr.c already gracefully handles this by using @$ as initial location
    for the errors.  Let's do that in yacc.c and lalr1.cc.
    
    * data/lalr1.cc, data/yacc.c: Use @$ to initialize the error location.
    * tests/actions.at: Check that case.


> Fortunately, there's an easy workaround for this bug: it's possible to move 
> mid-rule action to another rule, and the issue doesn't reproduce anymore:
> start:
>    one_two_three '4' '5' '6' { $$ = 0; }
> ;
> 
> one_two_three:
>    '1' '2' '3' { throw syntax_error(@1, "Test"); }
> ;
> 
> 
> And a small another bug: it's currently not possible to use syntax_error 
> class from outside grammar file, as it has inline constructor defined 
> (c++.m4), which makes this class non-constructible from other cpp files, at 
> least in Visual Studio 2015. Removing « inline" keyword solves this issue.

That was also addressed in 3.0.5.

Thanks a lot!


reply via email to

[Prev in Thread] Current Thread [Next in Thread]