diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2014-04-22 17:42:01 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-04-22 17:42:01 +0000 |
commit | 4ab423cd70ddc40a8b8306ec468ef6436b3540e4 (patch) | |
tree | a4b355f84c7dafacd5d50d5b3dc88b56fffb72bd /lib/Sema/SemaExprObjC.cpp | |
parent | 13e41baf7883704f60e86c06d794652330c2bd93 (diff) | |
download | clang-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.cpp | 20 |
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 && |