if (fname.endswith("Retain") ||
fname.find("Create") != StringRef::npos ||
fname.find("Copy") != StringRef::npos) {
+ // Do not migrate to couple of bridge transfer casts which
+ // cancel each other out. Leave it unchanged so error gets user
+ // attention instead.
+ if (FD->getName() == "CFRetain" &&
+ FD->getNumParams() == 1 &&
+ FD->getParent()->isTranslationUnit() &&
+ FD->getLinkage() == ExternalLinkage) {
+ Expr *Arg = callE->getArg(0);
+ if (const CastExpr *ICE = dyn_cast<CastExpr>(Arg)) {
+ const Expr *sub = ICE->getSubExpr();
+ QualType T = sub->getType();
+ if (T->isObjCObjectPointerType())
+ return;
+ }
+ }
castToObjCObject(E, /*retained=*/true);
return;
}
--- /dev/null
+// RUN: %clang_cc1 -arcmt-check -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -verify %s
+// DISABLE: mingw32
+// rdar://10387088
+typedef const void * CFTypeRef;
+
+extern
+CFTypeRef CFRetain(CFTypeRef cf);
+
+@interface INTF
+{
+ void *cf_format;
+ id objc_format;
+}
+@end
+
+@interface NSString
++ (id)stringWithFormat:(NSString *)format;
+@end
+
+@implementation INTF
+- (void) Meth {
+ NSString *result;
+
+ result = (id) CFRetain([NSString stringWithFormat:@"PBXLoopMode"]); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
+
+ result = (id) CFRetain((id)((objc_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
+
+ result = (id) CFRetain((id)((cf_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
+
+ result = (id) CFRetain((CFTypeRef)((objc_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
+
+ result = (id) CFRetain(cf_format); // OK
+}
+@end
+