[arcmt] Use __bridge_retained when passing an objc object to a CF parameter

annotated with cf_consumed attribute.

llvm-svn: 139709
This commit is contained in:
Argyrios Kyrtzidis 2011-09-14 18:17:09 +00:00
parent d4b5e3a4d9
commit 41899f3bac
4 changed files with 40 additions and 0 deletions

View File

@ -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))

View File

@ -4,6 +4,8 @@
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE
#endif
#define CF_CONSUMED __attribute__((cf_consumed))
#define nil ((void*) 0)
typedef int BOOL;

View File

@ -40,6 +40,8 @@ void f(BOOL b, id p) {
}
@end
extern void consumeParam(CFStringRef CF_CONSUMED p);
void f2(NSString *s) {
CFStringRef ref = [s string];
ref = (CFStringRef)[s string];
@ -53,4 +55,7 @@ void f2(NSString *s) {
ref = CFRetain([s string]);
ref = CFRetain(s);
ref = [s retain];
consumeParam((CFStringRef)s);
consumeParam(s);
}

View File

@ -40,6 +40,8 @@ void f(BOOL b, id p) {
}
@end
extern void consumeParam(CFStringRef CF_CONSUMED p);
void f2(NSString *s) {
CFStringRef ref = (__bridge CFStringRef)([s string]);
ref = (__bridge CFStringRef)[s string];
@ -53,4 +55,7 @@ void f2(NSString *s) {
ref = (__bridge_retained CFTypeRef)([s string]);
ref = (__bridge_retained CFTypeRef)(s);
ref = (__bridge_retained CFStringRef)(s);
consumeParam((__bridge_retained CFStringRef)s);
consumeParam((__bridge_retained CFStringRef)(s));
}