diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2013-11-20 00:32:12 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-11-20 00:32:12 +0000 |
commit | e100097e424fb1ead2957f7c083bafb960043888 (patch) | |
tree | 5416c951173c364222e6303ea1cc1df28f2101c1 /lib/Sema/SemaExprObjC.cpp | |
parent | ff453c293db06a887e9d82ac44ad284931cd4519 (diff) | |
download | clang-e100097e424fb1ead2957f7c083bafb960043888.tar.gz clang-e100097e424fb1ead2957f7c083bafb960043888.tar.bz2 clang-e100097e424fb1ead2957f7c083bafb960043888.tar.xz |
ObjectiveC ARC. validate toll free bridge casting
to or from 'id' and qualified-id types.
// rdar://15454846
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index cc8eacee61..6a0c09a4db 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -3196,14 +3196,24 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) { castType->getAsObjCInterfacePointerType()) { ObjCInterfaceDecl *CastClass = InterfacePointerType->getObjectType()->getInterface(); - if ((CastClass == ExprClass) || (CastClass && ExprClass->isSuperClassOf(CastClass))) + if ((CastClass == ExprClass) || + (CastClass && ExprClass->isSuperClassOf(CastClass))) return true; S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) << T << Target->getName() << castType->getPointeeType(); return true; - } else { + } else if (castType->isObjCIdType() || + (S.Context.ObjCObjectAdoptsQTypeProtocols( + castType, ExprClass))) + // ok to cast to 'id'. + // casting to id<p-list> is ok if bridge type adopts all of + // p-list protocols. + return true; + else { S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) << T << Target->getName() << castType; + S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + S.Diag(Target->getLocStart(), diag::note_declared_at); return true; } } @@ -3221,7 +3231,6 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) { return false; } -// (CFErrorRef)ns static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) { QualType T = castType; while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) { @@ -3240,16 +3249,25 @@ static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) { castExpr->getType()->getAsObjCInterfacePointerType()) { ObjCInterfaceDecl *ExprClass = InterfacePointerType->getObjectType()->getInterface(); - if ((CastClass == ExprClass) || (ExprClass && CastClass->isSuperClassOf(ExprClass))) + if ((CastClass == ExprClass) || + (ExprClass && CastClass->isSuperClassOf(ExprClass))) return true; S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf) << castExpr->getType()->getPointeeType() << T; S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); return true; - } else { + } else if (castExpr->getType()->isObjCIdType() || + (S.Context.QIdProtocolsAdoptObjCObjectProtocols( + castExpr->getType(), CastClass))) + // ok to cast an 'id' expression to a CFtype. + // ok to cast an 'id<plist>' expression to CFtype provided plist + // adopts all of CFtype's ObjetiveC's class plist. + return true; + else { S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf) << castExpr->getType() << castType; S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + S.Diag(Target->getLocStart(), diag::note_declared_at); return true; } } |