diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 32 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 17 |
3 files changed, 38 insertions, 23 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index d053d5a9e9..0721814c18 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -1717,7 +1717,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, Kind = CK_Dependent; return Owned(CastExpr); } - + + QualType origCastExprType = CastExpr->getType(); if (VK == VK_RValue && !CastTy->isRecordType()) { ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr); if (CastExprRes.isInvalid()) @@ -1773,8 +1774,15 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, } } - if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success) + if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success) { CheckObjCARCConversion(R, CastTy, CastExpr, CCK); + if (!CheckObjCARCUnavailableWeakConversion(CastTy, + origCastExprType)) + Diag(CastExpr->getLocStart(), + diag::err_arc_cast_of_weak_unavailable) + << origCastExprType << CastTy + << CastExpr->getSourceRange(); + } if (tcr != TC_Success && msg != 0) { if (CastExpr->getType() == Context.OverloadTy) { diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index cf03684c67..fea31aa046 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4066,22 +4066,12 @@ ExprResult Sema::CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyR, } } } - else { - QualType canCastType = - Context.getCanonicalType(castType).getUnqualifiedType(); - if (isa<ObjCObjectPointerType>(canCastType) && - castType.getObjCLifetime() == Qualifiers::OCL_Weak && - castExprType->isObjCObjectPointerType()) { - if (const ObjCObjectPointerType *ObjT = - castExprType->getAs<ObjCObjectPointerType>()) - if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) { - Diag(castExpr->getLocStart(), - diag::err_arc_cast_of_weak_unavailable) + else if (!CheckObjCARCUnavailableWeakConversion(castType, castExprType)) { + Diag(castExpr->getLocStart(), + diag::err_arc_cast_of_weak_unavailable) << castExprType << castType << castExpr->getSourceRange(); - return ExprError(); - } - } + return ExprError(); } } @@ -5300,12 +5290,8 @@ Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs, checkObjCPointerTypesForAssignment(*this, lhsType, rhsType); if (getLangOptions().ObjCAutoRefCount && result == Compatible && - origLhsType.getObjCLifetime() == Qualifiers::OCL_Weak) { - if (const ObjCObjectPointerType *ObjT = - rhsType->getAs<ObjCObjectPointerType>()) - if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) - result = IncompatibleObjCWeakRef; - } + !CheckObjCARCUnavailableWeakConversion(origLhsType, rhsType)) + result = IncompatibleObjCWeakRef; return result; } @@ -5474,8 +5460,12 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, ExprResult &rExpr) { AA_Assigning); if (Res.isInvalid()) return Incompatible; + Sema::AssignConvertType result = Compatible; + if (getLangOptions().ObjCAutoRefCount && + !CheckObjCARCUnavailableWeakConversion(lhsType, rExpr.get()->getType())) + result = IncompatibleObjCWeakRef; rExpr = move(Res); - return Compatible; + return result; } // FIXME: Currently, we fall through and treat C++ classes like C diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index fa51098f1a..22953da97b 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1771,6 +1771,23 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, << castRange << castExpr->getSourceRange(); } +bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType, + QualType exprType) { + QualType canCastType = + Context.getCanonicalType(castType).getUnqualifiedType(); + QualType canExprType = + Context.getCanonicalType(exprType).getUnqualifiedType(); + if (isa<ObjCObjectPointerType>(canCastType) && + castType.getObjCLifetime() == Qualifiers::OCL_Weak && + canExprType->isObjCObjectPointerType()) { + if (const ObjCObjectPointerType *ObjT = + canExprType->getAs<ObjCObjectPointerType>()) + if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) + return false; + } + return true; +} + /// Look for an ObjCReclaimReturnedObject cast and destroy it. static Expr *maybeUndoReclaimObject(Expr *e) { // For now, we just undo operands that are *immediately* reclaim |