[cfe-dev] Ownership of Stmts and Exprs, and destroying them
Sebastian Redl
sebastian.redl at getdesigned.at
Mon Nov 24 13:57:45 PST 2008
Chris Lattner wrote:
>
> On Nov 24, 2008, at 12:13 PM, Sebastian Redl wrote:
>
>> Chris Lattner wrote:
>>>
>>> On Nov 22, 2008, at 3:36 PM, Sebastian Redl wrote:
>>>> Is this correct? Because I want to clean this up. I want to make the
>>>> Sema routines (and later the parser, too) not leak. So I need to know
>>>> exactly how this works.
>>>
>>> This would be great. Probably the first place to start is to use
>>> audit the parser for places where early exits cause parsed stmts to
>>> be leaked.
>>
>> OK, I've audited the parser. The result is attached. No regressions,
>> and a clean valgrind run on Parse/statements.c. (Not leak-free. Just
>> invalid-access-free.)
>>
>> Not all places are fixed. In particular, array bounds and default
>> arguments hidden inside a Declarator might be leaked in some places.
>> Also, the additional guard is not pretty - ideally, ActionResult
>> itself should be replaced by the smart pointer. This is more of a
>> patch than a thorough solution.
>
> Cool!
>
> the Parser.cpp part is independent and can be committed separately
> (and looks fine)
>
> + class AstGuard {
>
> AST is a contraction, so it should be capitalized.
I don't particularly like making even abbreviations all-uppercase in
CamelCase names, but OK.
> The name "Guard" is somewhat strange for this. How about "ASTOwner"
> or "ASTHolder" or something like that?
I use Guard for most things that guard against early exit from a frame.
Or sentry, which is a synonym. I didn't use a name like Holder because
the ExprResult/ExprTy/Stmt equivalents aren't actually part of the class
- the class is an external addon to guard against early exit, and it
needs to be told to watch a variable that you already have.
>
> + public:
> + enum AstType {
> + Stmt,
> + Expr
> + };
>
> Would it make sense to make an ExprAstGuard and StmtAstGuard class
Yes.
> (or a template parameterized on ExprResult/StmtResult)?
Feels wrong.
> In other words, make this determination statically instead of
> dynamically?
Yes, it is. I went for the dynamic way because I didn't have any
immediately obvious idea of what to template on (and specializing
individual members is a hassle, if at all possible), and I didn't want
to duplicate the code.
But I think I should just make it
template <void (Action::*Destroyer)(void*)> class ASTGuard;
typedef ASTGuard<&Action::DestroyExpr> ExprGuard;
typedef ASTGuard<&Action::DestroyStmt> StmtGuard;
Then the destructor is
~ASTGuard() { (Actions.*Destroyer)(Node); }
with Node being a new name for AstElement. If the compiler is smart,
this should be equivalent to a direct function call.
>
> + // RAII guard for freeing SmallVectors of Stmts and Exprs on early
> exit
> + // in the parser.
> + class AstArrayGuard {
>
> instead of having a pointer to a smallvector, how about just making
> this contain the temporary smallvector?
I suppose that's possible in the actual cases where I use it. I didn't
before, because I wasn't sure where I would put it. And of course, this
means making it a template on the smallvector size.
Sebastian
More information about the cfe-dev
mailing list