This is an archive of the discontinued LLVM Phabricator instance.

[ObjC] Enter a new evaluation context before calling BuildBlockForLambdaConversion.
ClosedPublic

Authored by ahatanak on Apr 5 2016, 10:03 PM.

Details

Summary

Currently, when clang compiles the following code,

id test() {

return @{@"a": [](){}, @"b": [](){}};

}

it builds an AST that is incorrect:

ReturnStmt 0x10d080448
`-ExprWithCleanups 0x10d080428

|-cleanup Block 0x10d0801f0 // points to the second BlockDecl
  ...
  -BlockDecl 0x10d07f150 // First block
  ...
  -BlockDecl 0x10d0801f0 // Second block
  ...
    `-ExprWithCleanups 0x10d0801d0
       |-cleanup Block 0x10d07f150 // points to the first BlockDecl

The ExprWithCleanups for the ReturnStmt has only one block (the second block) in its cleanup list. The other block (the first block) is in the cleanup list of the ExprWithCleanups attached to the second block. This happens because Sema::ExprCleanupObjects is false when MaybeCreateExprWithCleanups is called in Sema::ActOnFinishFullExpr the first time, but is true when the function is called the second time (Sema::BuildBlockForLambdaConversion sets ExprCleanupObjects to true when it builds the block for the first lambda).

To fix this bug, this patch pushes a new evaluation context before calling BuildBlockForLambdaConversion. This ensures that Sema::ExprCleanupObjects is false when MaybeCreateExprWithCleanups is called the second time too.

Diff Detail

Repository
rL LLVM

Event Timeline

ahatanak updated this revision to Diff 52764.Apr 5 2016, 10:03 PM
ahatanak retitled this revision from to [ObjC] Enter a new evaluation context before calling BuildBlockForLambdaConversion..
ahatanak updated this object.
ahatanak added a subscriber: cfe-commits.
ahatanak updated this revision to Diff 56092.May 3 2016, 9:23 PM

Rebase and add reviewers.

This revision was automatically updated to reflect the committed changes.