summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-04-22 17:42:01 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-04-22 17:42:01 +0000
commit4ab423cd70ddc40a8b8306ec468ef6436b3540e4 (patch)
treea4b355f84c7dafacd5d50d5b3dc88b56fffb72bd /lib/Sema/SemaExprObjC.cpp
parent13e41baf7883704f60e86c06d794652330c2bd93 (diff)
downloadclang-4ab423cd70ddc40a8b8306ec468ef6436b3540e4.tar.gz
clang-4ab423cd70ddc40a8b8306ec468ef6436b3540e4.tar.bz2
clang-4ab423cd70ddc40a8b8306ec468ef6436b3540e4.tar.xz
Objective-C ARC. Under ARC, addition of 'bridge' attribute
on CF type is not sufficient and bridge casting is still required for proper ownership semantics. // rdar://16650445 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206910 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 8dd319c98b..d316c13f94 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -3289,7 +3289,8 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
}
template <typename TB>
-static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+ bool TollFreeBridgeCast) {
QualType T = castExpr->getType();
while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
TypedefNameDecl *TDNDecl = TD->getDecl();
@@ -3308,8 +3309,15 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
ObjCInterfaceDecl *CastClass
= InterfacePointerType->getObjectType()->getInterface();
if ((CastClass == ExprClass) ||
- (CastClass && ExprClass->isSuperClassOf(CastClass)))
+ (CastClass && ExprClass->isSuperClassOf(CastClass))) {
+ if (!TollFreeBridgeCast && S.getLangOpts().ObjCAutoRefCount) {
+ // bridge attribute is ok. However, under ARC, cast still requires
+ // an explicit cast and should not compile under ARC.
+ S.Diag(castExpr->getLocStart(), diag::err_objc_invalid_bridge)
+ << T << Target->getName();
+ }
return true;
+ }
S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
<< T << Target->getName() << castType->getPointeeType();
return true;
@@ -3402,8 +3410,8 @@ void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
- (void)CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr);
- (void)CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+ (void)CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, true);
+ (void)CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, true);
}
else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
(void)CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr);
@@ -3624,8 +3632,8 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation &&
(CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast))
- if (CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr) ||
- CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr))
+ if (CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, false) ||
+ CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, false))
return ACR_okay;
if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&