diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 7ed3942332..5b7fb4656d 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3846,14 +3846,15 @@ enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar }; /// Determines whether this expression is an acceptable ICR source. static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, - bool isAddressOf) { + bool isAddressOf, bool &isWeakAccess) { // Skip parens. e = e->IgnoreParens(); // Skip address-of nodes. if (UnaryOperator *op = dyn_cast<UnaryOperator>(e)) { if (op->getOpcode() == UO_AddrOf) - return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true); + return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true, + isWeakAccess); // Skip certain casts. } else if (CastExpr *ce = dyn_cast<CastExpr>(e)) { @@ -3862,7 +3863,7 @@ static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, case CK_BitCast: case CK_LValueBitCast: case CK_NoOp: - return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf); + return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf, isWeakAccess); case CK_ArrayToPointerDecay: return IIK_nonscalar; @@ -3876,6 +3877,11 @@ static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, // If we have a declaration reference, it had better be a local variable. } else if (isa<DeclRefExpr>(e)) { + // set isWeakAccess to true, to mean that there will be an implicit + // load which requires a cleanup. + if (e->getType().getObjCLifetime() == Qualifiers::OCL_Weak) + isWeakAccess = true; + if (!isAddressOf) return IIK_nonlocal; VarDecl *var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl()); @@ -3885,10 +3891,11 @@ static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, // If we have a conditional operator, check both sides. } else if (ConditionalOperator *cond = dyn_cast<ConditionalOperator>(e)) { - if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf)) + if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf, + isWeakAccess)) return iik; - return isInvalidICRSource(C, cond->getRHS(), isAddressOf); + return isInvalidICRSource(C, cond->getRHS(), isAddressOf, isWeakAccess); // These are never scalar. } else if (isa<ArraySubscriptExpr>(e)) { @@ -3907,8 +3914,13 @@ static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, /// indirect copy/restore. static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) { assert(src->isRValue()); - - InvalidICRKind iik = isInvalidICRSource(S.Context, src, false); + bool isWeakAccess = false; + InvalidICRKind iik = isInvalidICRSource(S.Context, src, false, isWeakAccess); + // If isWeakAccess to true, there will be an implicit + // load which requires a cleanup. + if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess) + S.ExprNeedsCleanups = true; + if (iik == IIK_okay) return; S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback) |