diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-06-21 17:38:29 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-06-21 17:38:29 +0000 |
commit | af9751747b098d77052cb71f1e648f29cfbadcc1 (patch) | |
tree | b0d391080be0a9d8962d361160daaffd6958ddbd /lib | |
parent | 14d251cd62942bf7d56bb87a267ba2ca2f7fae3e (diff) |
objc-arc: CodeGen part of unbridged cast of CF types.
// rdar://9474349
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 46 |
2 files changed, 47 insertions, 8 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 0b3083aaa6..5f1a355c8a 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -641,8 +641,9 @@ CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType); } } else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) { + Expr *Exp = SrcExpr.get(); Self.CheckObjCARCConversion(OpRange, DestType, - SrcExpr.get(), Sema::CCK_OtherCast); + Exp, Sema::CCK_OtherCast); } } @@ -704,9 +705,11 @@ CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, } else if (tcr == TC_Success) { if (Kind == CK_BitCast) Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); - if (Self.getLangOptions().ObjCAutoRefCount) + if (Self.getLangOptions().ObjCAutoRefCount) { + Expr *Exp = SrcExpr.get(); Self.CheckObjCARCConversion(OpRange, DestType, - SrcExpr.get(), Sema::CCK_OtherCast); + Exp, Sema::CCK_OtherCast); + } } else if (Kind == CK_BitCast) Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 02dd4a1a3e..ff3f837bac 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1551,14 +1551,50 @@ namespace { } bool -Sema::ValidObjCARCNoBridgeCastExpr(const Expr *Exp) { - Exp = Exp->IgnoreParenImpCasts(); - return isa<ObjCMessageExpr>(Exp) || isa<ObjCPropertyRefExpr>(Exp); +Sema::ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType) { + Expr *NewExp = Exp->IgnoreParenImpCasts(); + + if (!isa<ObjCMessageExpr>(NewExp) && !isa<ObjCPropertyRefExpr>(NewExp)) + return false; + ObjCMethodDecl *method = 0; + if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(NewExp)) { + method = PRE->getExplicitProperty()->getGetterMethodDecl(); + } + else { + ObjCMessageExpr *ME = cast<ObjCMessageExpr>(NewExp); + method = ME->getMethodDecl(); + } + if (!method) + return false; + if (method->hasAttr<CFReturnsNotRetainedAttr>()) + return true; + bool MethodReturnsPlusOne = method->hasAttr<CFReturnsRetainedAttr>(); + if (!MethodReturnsPlusOne) { + ObjCMethodFamily family = method->getSelector().getMethodFamily(); + switch (family) { + case OMF_alloc: + case OMF_copy: + case OMF_mutableCopy: + case OMF_new: + MethodReturnsPlusOne = true; + break; + default: + break; + } + } + if (MethodReturnsPlusOne) { + TypeSourceInfo *TSInfo = + Context.getTrivialTypeSourceInfo(castType, SourceLocation()); + ExprResult ExpRes = BuildObjCBridgedCast(SourceLocation(), OBC_BridgeTransfer, + SourceLocation(), TSInfo, Exp); + Exp = ExpRes.take(); + } + return true; } void Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, - Expr *castExpr, CheckedConversionKind CCK) { + Expr *&castExpr, CheckedConversionKind CCK) { QualType castExprType = castExpr->getType(); ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType); @@ -1614,7 +1650,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, castExprType->isCARCBridgableType()) { // explicit unbridged casts are allowed if the source of the cast is a // message sent to an objc method (or property access) - if (ValidObjCARCNoBridgeCastExpr(castExpr)) + if (ValidObjCARCNoBridgeCastExpr(castExpr, castType)) return; Diag(loc, diag::err_arc_cast_requires_bridge) << 2 |