diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-09-14 18:17:09 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-09-14 18:17:09 +0000 |
commit | 4532b5553db699d5bed250454f9a45e0f66f4bf8 (patch) | |
tree | c8429403cb0c1f649fa62b5cb7907d6bea5f50b2 /lib/ARCMigrate/TransUnbridgedCasts.cpp | |
parent | 528a499eb84d61667f65b16a13780c135b822f6b (diff) |
[arcmt] Use __bridge_retained when passing an objc object to a CF parameter
annotated with cf_consumed attribute.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139709 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate/TransUnbridgedCasts.cpp')
-rw-r--r-- | lib/ARCMigrate/TransUnbridgedCasts.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp index bc33c53b75..047dfb276a 100644 --- a/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -242,6 +242,11 @@ private: if (implCE->getCastKind() == CK_ARCReclaimReturnedObject) return rewriteToBridgedCast(E, OBC_Bridge); } + + bool isConsumed = false; + if (isPassedToCParamWithKnownOwnership(E, isConsumed)) + return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained + : OBC_Bridge); } static ObjCMethodFamily getFamilyOfMessage(Expr *E) { @@ -265,6 +270,29 @@ private: return false; } + bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const { + if (CallExpr *callE = dyn_cast_or_null<CallExpr>( + StmtMap->getParentIgnoreParenImpCasts(E))) + if (FunctionDecl * + FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) { + unsigned i = 0; + for (unsigned e = callE->getNumArgs(); i != e; ++i) { + Expr *arg = callE->getArg(i); + if (arg == E || arg->IgnoreParenImpCasts() == E) + break; + } + if (i < callE->getNumArgs()) { + ParmVarDecl *PD = FD->getParamDecl(i); + if (PD->getAttr<CFConsumedAttr>()) { + isConsumed = true; + return true; + } + } + } + + return false; + } + bool isSelf(Expr *E) const { E = E->IgnoreParenLValueCasts(); if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) |