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 | d9bb743e0d343b3a199e218368b33f52f4886a72 (patch) | |
tree | f5328f00546cc49004c1f10f5d5a71e97bd1b0d4 /clang/lib/CodeGen | |
parent | a94a1544d8d0ae7b54b5a78300e46e81b267e2f9 (diff) | |
download | bcm5719-llvm-d9bb743e0d343b3a199e218368b33f52f4886a72.tar.gz bcm5719-llvm-d9bb743e0d343b3a199e218368b33f52f4886a72.zip |
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.
llvm-svn: 136271
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index c2978039b1a..6d9b5b33747 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -288,21 +288,26 @@ void CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S, llvm::Function *syncEnterFn, llvm::Function *syncExitFn) { - // Evaluate the lock operand. This should dominate the cleanup. - llvm::Value *SyncArg = - CGF.EmitScalarExpr(S.getSynchExpr()); + CodeGenFunction::RunCleanupsScope cleanups(CGF); + + // Evaluate the lock operand. This is guaranteed to dominate the + // ARC release and lock-release cleanups. + const Expr *lockExpr = S.getSynchExpr(); + llvm::Value *lock; + if (CGF.getLangOptions().ObjCAutoRefCount) { + lock = CGF.EmitARCRetainScalarExpr(lockExpr); + lock = CGF.EmitObjCConsumeObject(lockExpr->getType(), lock); + } else { + lock = CGF.EmitScalarExpr(lockExpr); + } + lock = CGF.Builder.CreateBitCast(lock, CGF.VoidPtrTy); // Acquire the lock. - SyncArg = CGF.Builder.CreateBitCast(SyncArg, syncEnterFn->getFunctionType()->getParamType(0)); - CGF.Builder.CreateCall(syncEnterFn, SyncArg); + CGF.Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow(); // Register an all-paths cleanup to release the lock. - CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn, - SyncArg); + CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn, lock); // Emit the body of the statement. CGF.EmitStmt(S.getSynchBody()); - - // Pop the lock-release cleanup. - CGF.PopCleanupBlock(); } |