help-bison
[Top][All Lists]
Advanced

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

Re: RAII techniques in semantic actions leading to double deletion


From: John Horigan
Subject: Re: RAII techniques in semantic actions leading to double deletion
Date: Thu, 6 Dec 2012 13:41:36 -0800

I am using %skeleton "lalr1.cc" and I have %destructor declarations
for all my pointers so that they don't leak when there is a syntax
error.

I added all of the auto_ptrs to get rid of clutter, the clutter of
deleting symbols along code paths where they don't end up getting
owned by anyone.

I added $n = 0; assignments to every place in my grammar where a
symbol was owned by auto_ptr<> and my parser now survives C++
exceptions without incident. I think that this is just a documentation
issue. When you add exception safety to the manual you should talk
about the parser retaining ownership of the symbols for the current
action and what the action needs to do if this conflicts with its own
memory management.

-- john

On Thu, Dec 6, 2012 at 12:11 AM, Akim Demaille <address@hidden> wrote:
> Hi John,
>
> Le 5 déc. 2012 à 21:43, John Horigan <address@hidden> a écrit :
>
>> My C++ grammar file is littered with code like this:
>>
>> sizetime:
>>        MODTYPE modification_v2 {
>>            exp_ptr mod($2);
>>            driver.lexer->maybeVersion = token::CFDG2;
>>            if ($1 != ASTmodTerm::size && $1 != ASTmodTerm::time) {
>>                error(@1, "Syntax error");
>>            } else {
>>                static const std::string sizeVar("CF::Size");
>>                static const std::string timeVar("CF::Time");
>>                driver.NextParameter($1 == ASTmodTerm::size ? sizeVar
>> : timeVar, mod, @1, @2);
>>            }
>>            $$ = 0;
>>        }
>>        ;
>>
>>
>> exp_ptr is a typedef for std::auto_ptr<expression_t>
>>
>> The general idea is that the semantic values get automatically deleted
>> if nothing in the action takes ownership of them. This served me well
>> until recently, when I had a bug where an action threw an exception.
>> The std::auto_ptr<> deleted the semantic values and then the parser
>> caught the exception and tried to delete the semantic values a second
>> time.
>
> Could you be more specific about this deletion?  It looks like
> you are dealing with pointers, so the parser should not try to
> delete anything, unless you specified a %destructor.
>
> Also, what skeleton are you using?
>
> I tend to think this is a lot of clutter, not to mention the
> (small) penalty for constructing all these guys.  Bison comes
> with warnings when you forget mentioning some rhs member that
> has a value, and valgrind can help catching the missing ones.
> Shouldn't that suffice?
>
>> One way to think about this is that it is an error for the action to
>> delete a semantic value if there is any chance that the action can
>> exit through an exception (or YYERROR, YYABORT, etc). But I really
>> prefer to use RAII whenever I can.
>>
>> Can I solve the problem by changing all of my auto_ptr<> declarations from 
>> this:
>>
>>            exp_ptr mod($2);
>>
>> to this:
>>
>>            exp_ptr mod($2); $2 = 0;
>>
>> to explicitly move ownership from the semantic value stack to my
>> auto_ptr<>? Would this actually do what I think it does and can I
>> still use @2 after erasing $2?
>
> That would work.  $2 and @2 are unrelated, changing one won't
> change the other.



reply via email to

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