From 4f53cbe431f529fc2bd62c2c8020791eb85d0d4d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 4 May 2016 18:07:20 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@268527 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 3 +++ test/SemaObjCXX/block-cleanup.mm | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 test/SemaObjCXX/block-cleanup.mm diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 88f2bc798a..e11d9c84fe 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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; diff --git a/test/SemaObjCXX/block-cleanup.mm b/test/SemaObjCXX/block-cleanup.mm new file mode 100644 index 0000000000..0c6a6d8c26 --- /dev/null +++ b/test/SemaObjCXX/block-cleanup.mm @@ -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": [](){}}; +} -- 2.50.1