diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 37 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 20 |
2 files changed, 38 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 56161ed9b45..5825d6b9b6e 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/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)); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 373339a2cb8..12eba297999 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1181,15 +1181,22 @@ public: return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); } + /// \brief Rebuild the operand to an Objective-C @synchronized statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, + Expr *object) { + return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object); + } + /// \brief Build a new Objective-C @synchronized statement. /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, - Expr *Object, - Stmt *Body) { - return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, - Body); + Expr *Object, Stmt *Body) { + return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); } /// \brief Build a new Objective-C @autoreleasepool statement. @@ -5479,6 +5486,11 @@ TreeTransform<Derived>::TransformObjCAtSynchronizedStmt( ExprResult Object = getDerived().TransformExpr(S->getSynchExpr()); if (Object.isInvalid()) return StmtError(); + Object = + getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(), + Object.get()); + if (Object.isInvalid()) + return StmtError(); // Transform the body. StmtResult Body = getDerived().TransformStmt(S->getSynchBody()); |