diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 68b767b474..cf03684c67 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4065,6 +4065,23 @@ ExprResult Sema::CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyR, return ExprError(); } } + } + 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) + << castExprType << castType + << castExpr->getSourceRange(); + return ExprError(); + } + } } } @@ -5124,6 +5141,7 @@ Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs, CastKind &Kind) { QualType rhsType = rhs.get()->getType(); + QualType origLhsType = lhsType; // Get canonical types. We're not formatting these types, just comparing // them. @@ -5278,7 +5296,17 @@ Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs, // A* -> B* if (rhsType->isObjCObjectPointerType()) { Kind = CK_BitCast; - return checkObjCPointerTypesForAssignment(*this, lhsType, rhsType); + Sema::AssignConvertType result = + 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; + } + return result; } // int or null -> A* @@ -8679,6 +8707,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, case IncompatibleVectors: DiagKind = diag::warn_incompatible_vectors; break; + case IncompatibleObjCWeakRef: + DiagKind = diag::err_arc_weak_unavailable_assign; + break; case Incompatible: DiagKind = diag::err_typecheck_convert_incompatible; isInvalid = true; |