[cfe-dev] CFG support for temporary object desctructors

Jordan Rose jordan_rose at apple.com
Wed Jul 10 10:39:04 PDT 2013


On Jul 2, 2013, at 7:01 , Pavel Labath <labath at google.com> wrote:

> 
> 
> 
> On 2 July 2013 03:47, Jordan Rose <jordan_rose at apple.com> wrote:
> The byVal case is interesting in a different way:
> 
> `-FunctionDecl 0x7f8be1030b60 <line:3:1, line:6:1> test 'void (void)'
>   `-CompoundStmt 0x7f8be1061ab0 <line:3:13, line:6:1>
>     |-DeclStmt 0x7f8be1061588 <line:4:2, col:20>
>     | `-FunctionDecl 0x7f8be10614e0 <col:2, col:19> byVal 'void (struct Object)'
>     |   `-ParmVarDecl 0x7f8be1061420 <col:13, col:19> 'struct Object'
>     `-ExprWithCleanups 0x7f8be1061a98 <line:5:2, col:16> 'void'
>       `-CallExpr 0x7f8be1061980 <col:2, col:16> 'void'
>         |-ImplicitCastExpr 0x7f8be1061968 <col:2> 'void (*)(struct Object)' <FunctionToPointerDecay>
>         | `-DeclRefExpr 0x7f8be10615a0 <col:2> 'void (struct Object)' lvalue Function 0x7f8be10614e0 'byVal' 'void (struct Object)'
>         `-CXXBindTemporaryExpr 0x7f8be1061a78 <col:8, col:15> 'struct Object' (CXXTemporary 0x7f8be1061a70)
>           `-CXXConstructExpr 0x7f8be1061a38 <col:8, col:15> 'struct Object' 'void (const struct Object &) throw()' elidable
>             `-MaterializeTemporaryExpr 0x7f8be10619c8 <col:8, col:15> 'const struct Object' lvalue
>               `-ImplicitCastExpr 0x7f8be10619b0 <col:8, col:15> 'const struct Object' <NoOp>
>                 `-CXXBindTemporaryExpr 0x7f8be1061918 <col:8, col:15> 'struct Object' (CXXTemporary 0x7f8be1061910)
>                   `-CXXTemporaryObjectExpr 0x7f8be10618d0 <col:8, col:15> 'struct Object' 'void (void)' zeroing
> 
> Here we get an extra CXXConstructExpr and CXXBindTemporaryExpr, which is copying the temporary into the argument. However, at the time we evaluate the CXXConstructExpr, we don't yet know if we're going to be able to inline the whole call. If we do, we need to make sure the VarRegion for the by-value parameter contains the constructed object...once we've built the stack frame it's in. We probably want to run the destructor within the inlined function as well. If we don't inline the function, we either need to run the destructor outside the function, or elide the copy-constructor altogether and just destroy the original temporary.
> 
> Certainly you could say our representation of rvalue structs is what's causing the problem, or at least part of the problem. Certainly knowing which region to destroy is a big part of this. But we haven't thought about what it would take to solve the problem, or if changing the representation would actually help solve everything.
> 
> I have also noticed a different problem. A pattern like
> void foo() {
>   static const Object &ref = Object();
> }
> will be flagged as an error (dangling reference after function return), when in fact this code is ok. I guess this is also related to the problem of not knowing which region to construct the temporary object into, since this object shouldn't be constructed on the stack.

Hm...point. Not sure what we'll do about this one—maybe check if we're on a static initialization branch. (The analyzer puts a fake branch in the CFG to decide whether we're initializing a static variable.) Please file a bug so that we can track it, at least.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130710/a7649701/attachment.html>


More information about the cfe-dev mailing list