[ObjC] Enter a new evaluation context before calling

BuildBlockForLambdaConversion.

Previously, clang would build an incorrect AST for the following code:

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

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

To fix the bug, this commit enters a new evaluation context to reset
ExprNeedsCleanups before each block is parsed.

rdar://problem/16879958

Differential Revision: http://reviews.llvm.org/D18815

llvm-svn: 268527
This commit is contained in:
Akira Hatanaka 2016-05-04 18:07:20 +00:00
parent 1a14f0d25c
commit c482acd2e5
2 changed files with 19 additions and 0 deletions

View File

@ -6229,9 +6229,12 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
// follows the normal lifetime rules for block literals instead of being
// autoreleased.
DiagnosticErrorTrap Trap(Diags);
PushExpressionEvaluationContext(PotentiallyEvaluated);
ExprResult Exp = BuildBlockForLambdaConversion(E->getExprLoc(),
E->getExprLoc(),
Method, E);
PopExpressionEvaluationContext();
if (Exp.isInvalid())
Diag(E->getExprLoc(), diag::note_lambda_to_block_conv);
return Exp;

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -std=gnu++11 -o /dev/null -x objective-c++ -fblocks -ast-dump %s 2>&1 | FileCheck %s
// CHECK: -FunctionDecl {{.*}} test 'id (void)'
// CHECK-NEXT: -CompoundStmt
// CHECK-NEXT: -ReturnStmt
// CHECK-NEXT: -ExprWithCleanups
// CHECK-NEXT: -cleanup Block
// CHECK-NEXT: -cleanup Block
@interface NSDictionary
+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
@end
id test() {
return @{@"a": [](){}, @"b": [](){}};
}