diff options
author | John McCall <rjmccall@apple.com> | 2011-07-27 21:50:02 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-27 21:50:02 +0000 |
commit | 07524039dce5c820f111a1b3f772b4261f004b4a (patch) | |
tree | a796032fe9a98b7216910a08f50a405fa2ec9847 /lib/Sema/SemaStmt.cpp | |
parent | a2ee20aa9660851080135219cac5b31fbac08b78 (diff) |
The lock operand to an @synchronized statement is also
supposed to be a full-expression; make it so. In ARC, make sure
we retain the lock for the entire protected block.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136271 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 56161ed9b4..5825d6b9b6 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2232,25 +2232,32 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, return BuildObjCAtThrowStmt(AtLoc, Throw); } -StmtResult -Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr, - Stmt *SyncBody) { - getCurFunction()->setHasBranchProtectedScope(); - - ExprResult Result = DefaultLvalueConversion(SyncExpr); - if (Result.isInvalid()) - return StmtError(); +ExprResult +Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { + ExprResult result = DefaultLvalueConversion(operand); + if (result.isInvalid()) + return ExprError(); + operand = result.take(); - SyncExpr = Result.take(); // Make sure the expression type is an ObjC pointer or "void *". - if (!SyncExpr->getType()->isDependentType() && - !SyncExpr->getType()->isObjCObjectPointerType()) { - const PointerType *PT = SyncExpr->getType()->getAs<PointerType>(); - if (!PT || !PT->getPointeeType()->isVoidType()) - return StmtError(Diag(AtLoc, diag::error_objc_synchronized_expects_object) - << SyncExpr->getType() << SyncExpr->getSourceRange()); + QualType type = operand->getType(); + if (!type->isDependentType() && + !type->isObjCObjectPointerType()) { + const PointerType *pointerType = type->getAs<PointerType>(); + if (!pointerType || !pointerType->getPointeeType()->isVoidType()) + return Diag(atLoc, diag::error_objc_synchronized_expects_object) + << type << operand->getSourceRange(); } + // The operand to @synchronized is a full-expression. + return MaybeCreateExprWithCleanups(operand); +} + +StmtResult +Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr, + Stmt *SyncBody) { + // We can't jump into or indirect-jump out of a @synchronized block. + getCurFunction()->setHasBranchProtectedScope(); return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody)); } |