[cfe-commits] [Review] Partial fix for PR 11645: put destructor calls before a return statement.

Chandler Carruth chandlerc at google.com
Mon Jan 16 22:02:01 PST 2012


On Mon, Jan 16, 2012 at 9:29 PM, Ted Kremenek <kremenek at apple.com> wrote:

>  Hi Erik,
>
> Thanks for working on this.  I've commented in the PR.
>
> My concern is that I am having second thoughts about whether or not this
> is the right direction.  If there are temporaries in the return expression,
> should those destructors appear before the 'return' statement (but after
> the subexpression of 'return' gets evaluated)?  I can see it both ways.
>
> For example:
>
>   return A();
>
> where 'A' converts to whatever the return value type should be, and ~A()
> is non-trivial.  Technically, ~A() evaluates after the enclosing statement.
>  We're giving 'return' special treatment in your patch.
>
> One clean representation of this is to put all the destructors after the
> 'return' in the CFGBlock.  The other way is to have the destructors appear
> after the subexpression of 'return', but before the 'return' itself.  The
> former requires clients of the CFG to rethink where they expect 'return' to
> be in a CFGBlock.
>
> What do you think?
>

If I can jump in from the peanut gallery...

This doesn't seem a necessarily unique problem to return statements. Any
statement which forms a CFGBlock terminator and which contains temporaries
with destructors should hit the same issue. The other example is I suspect
throw. It may even be possible to trigger this with an indirect goto if the
index into the label-address array involves temporary objects.

I think the C++ standard* provides some help in making a choice about how
to represent this. It doesn't actually say that ~A() evaluates after the
enclosing statement. Instead it defines 'full-expressions' as an expression
which is not a subexpression of any other expression ([intro.execution]
1.9p10). As *part* of this full-expression, all temporary objects'
non-trivial destructors must be called ([class.temporary] 12.2p3). To me,
that indicates that the destructor should be placed after the complete
subexpression in the return statement, but within the return statement
itself. This has the nice property of preserving the (very useful!)
invariant that terminator statements are the last statement in the CFG
block.

-Chandler

[*] I'm citing the C++11 standard here as it provides clearer execution
semantics and wording here... I don't believe there is anything
substantively different between the standards though.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120116/7769bf86/attachment.html>


More information about the cfe-commits mailing list