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.