aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaCXXCast.cpp12
-rw-r--r--lib/Sema/SemaExpr.cpp32
-rw-r--r--lib/Sema/SemaExprObjC.cpp17
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