[cfe-commits] [Review] Partial fix for PR 11645: put destructor calls before a return statement.
Erik Verbruggen
erik.verbruggen at me.com
Tue Jan 17 06:36:31 PST 2012
I agree that leaving it as it is would make code generation easier for
most cases. However, I think we have the return-value-slot problem anyway:
class A {
public:
A();
~A();
};
A test() {
A a;
return a;
}
Generates:
[B3 (ENTRY)]
Succs (1): B2
[B1]
1: [B2.2].~A() (Implicit destructor)
Succs (1): B0
[B2]
1: (CXXConstructExpr, class A)
2: A a;
3: a
4: [B2.3] (ImplicitCastExpr, NoOp, const class A)
5: [B2.4] (CXXConstructExpr, class A)
6: return [B2.5];
7: [B2.2].~A() (Implicit destructor)
Preds (1): B3
Succs (1): B0
[B0 (EXIT)]
Preds (2): B1 B2
So to find out that we need to construct A in the return value slot in
B2.5, we need to look ahead to B2.6.
Also, I think that Ted pointed to another test-case which is then
incorrect:
class A {
public:
A();
~A();
};
A test() {
return A();
}
Generates:
[B2 (ENTRY)]
Succs (1): B1
[B1]
1: A() (CXXConstructExpr, class A)
2: [B1.1] (BindTemporary)
3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
4: [B1.3]
5: [B1.4] (CXXConstructExpr, class A)
6: ~A() (Temporary object destructor)
7: return [B1.5];
Preds (1): B2
Succs (1): B0
[B0 (EXIT)]
Preds (1): B1
In the mean time I'll see if I can find out where the extra joint points
get generated.
-- Erik.
On 17-1-12 7:18, Xu Zhongxing wrote:
> I think the first approach makes more sense from a pragmatic point of
> view. The semantics of the return stmt 'return A();' has 3 parts:
> 1. construct temp object A().
> 2. copy the object into the return value slot.
> 3. destruct A().
> Since in the analyzer the CFG is linearized, we have to no way to know
> that the temp object A() should be copied into the return value slot
> (whatever this means for the analysis engine) until we see the
> ReturnStmt. But if the dtor is put before the ReturnStmt, the temp
> object is already destructed when we want to return it.
>
> So the ReturnStmt is the indicator that the returned value should be
> prepared. We should not destruct the object before that.
>
> Plus, the ReturnStmt is not handled as block terminator in the CFG
> builder currently. It is only treated as a normal block element.
>
> On Tue, Jan 17, 2012 at 1:29 PM, Ted Kremenek <kremenek at apple.com
> <mailto: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?
>
> Ted
>
> On Thursday, January 12, 2012 at 6:30 AM, Erik Verbruggen wrote:
>
>> Hello,
>>
>> Attached is a patch for one of the things mentioned in PR 11645,
>> which
>> is that in the CFG the destructor calls end up after the return
>> statement.
>>
>> -- Erik.
>>
>> Attachments:
>> - 0001-CFG-Partial-fix-for-PR-11645-put-destructor-calls-be.patch
>
>
More information about the cfe-commits
mailing list