r188816 - ObjectiveC migrator: More tweaking of heuristics
Fariborz Jahanian
fjahanian at apple.com
Tue Aug 20 11:54:39 PDT 2013
Author: fjahanian
Date: Tue Aug 20 13:54:39 2013
New Revision: 188816
URL: http://llvm.org/viewvc/llvm-project?rev=188816&view=rev
Log:
ObjectiveC migrator: More tweaking of heuristics
for an audited cf function and addition of
a test case.
Modified:
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m
cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result
Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=188816&r1=188815&r2=188816&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Tue Aug 20 13:54:39 2013
@@ -775,16 +775,22 @@ static bool IsVoidStarType(QualType Ty)
return IsVoidStarType(PT->getPointeeType());
}
+/// AuditedType - This routine audits the type AT and returns false if it is one of known
+/// CF object types or of the "void *" variety. It returns true if we don't care about the type
+/// such as a non-pointer or pointers which have no ownership issues (such as "int *").
static bool
-AuditedType (QualType AT) {
- if (!AT->isPointerType())
+AuditedType (QualType AT, bool &IsPoniter) {
+ IsPoniter = (AT->isAnyPointerType() || AT->isBlockPointerType());
+ if (!IsPoniter)
return true;
- if (IsVoidStarType(AT))
- return false;
-
// FIXME. There isn't much we can say about CF pointer type; or is there?
- if (ento::coreFoundation::isCFObjectRef(AT))
+ if (ento::coreFoundation::isCFObjectRef(AT) ||
+ IsVoidStarType(AT) ||
+ // If an ObjC object is type, assuming that it is not a CF function and
+ // that it is an un-audited function.
+ AT->isObjCObjectPointerType())
return false;
+ // All other pointers are assumed audited as harmless.
return true;
}
@@ -811,10 +817,10 @@ void ObjCMigrateASTConsumer::migrateCFFu
const FunctionDecl *FirstFD = CFFunctionIBCandidates[0];
const FunctionDecl *LastFD =
CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
- const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n";
+ const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
edit::Commit commit(*Editor);
commit.insertBefore(FirstFD->getLocStart(), PragmaString);
- PragmaString = "\nCF_IMPLICIT_BRIDGING_DISABLED\n";
+ PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
SourceLocation EndLoc = LastFD->getLocEnd();
// get location just past end of function location.
EndLoc = PP.getLocForEndOfToken(EndLoc);
@@ -837,6 +843,7 @@ bool ObjCMigrateASTConsumer::migrateAddF
const FunctionDecl *FuncDecl) {
if (FuncDecl->hasBody())
return false;
+ bool HasAtLeastOnePointer = false;
CallEffects CE = CallEffects::getEffect(FuncDecl);
if (!FuncDecl->getAttr<CFReturnsRetainedAttr>() &&
!FuncDecl->getAttr<CFReturnsNotRetainedAttr>()) {
@@ -854,10 +861,14 @@ bool ObjCMigrateASTConsumer::migrateAddF
edit::Commit commit(*Editor);
commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString);
Editor->commit(commit);
+ HasAtLeastOnePointer = true;
}
- else if (!AuditedType(FuncDecl->getResultType()))
+ else if (!AuditedType(FuncDecl->getResultType(), HasAtLeastOnePointer))
return false;
}
+ else
+ HasAtLeastOnePointer = true;
+
// At this point result type is either annotated or audited.
// Now, how about argument types.
llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
@@ -865,18 +876,21 @@ bool ObjCMigrateASTConsumer::migrateAddF
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
ArgEffect AE = AEArgs[i];
- if (AE == DecRefMsg /*NSConsumed annotated*/ ||
- AE == DecRef /*CFConsumed annotated*/)
+ if (AE == DecRef /*CFConsumed annotated*/ ||
+ AE == IncRef) {
+ HasAtLeastOnePointer = true;
continue;
+ }
- if (AE != DoNothing && AE != MayEscape)
- return false;
const ParmVarDecl *pd = *pi;
QualType AT = pd->getType();
- if (!AuditedType(AT))
+ bool IsPointer;
+ if (!AuditedType(AT, IsPointer))
return false;
+ else if (IsPointer)
+ HasAtLeastOnePointer = true;
}
- return true;
+ return HasAtLeastOnePointer;
}
void ObjCMigrateASTConsumer::migrateObjCMethodDeclAnnotation(
Modified: cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m?rev=188816&r1=188815&r2=188816&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m (original)
+++ cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m Tue Aug 20 13:54:39 2013
@@ -3,6 +3,22 @@
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
+#ifndef CF_IMPLICIT_BRIDGING_ENABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin")
+#else
+#define CF_IMPLICIT_BRIDGING_ENABLED
+#endif
+#endif
+
+#ifndef CF_IMPLICIT_BRIDGING_DISABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end")
+#else
+#define CF_IMPLICIT_BRIDGING_DISABLED
+#endif
+#endif
+
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
#endif
@@ -2020,3 +2036,8 @@ void rdar13783514(xpc_connection_t conne
xpc_connection_set_context(connection, [[NSMutableArray alloc] init]);
xpc_connection_set_finalizer_f(connection, releaseAfterXPC);
} // no-warning
+
+CFAttributedStringRef CFAttributedCreate(long attributes) CF_RETURNS_RETAINED;
+CFTypeID CFGetTypeID(void) {
+ return 0;
+}
Modified: cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result?rev=188816&r1=188815&r2=188816&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result (original)
+++ cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result Tue Aug 20 13:54:39 2013
@@ -3,6 +3,22 @@
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
+#ifndef CF_IMPLICIT_BRIDGING_ENABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin")
+#else
+#define CF_IMPLICIT_BRIDGING_ENABLED
+#endif
+#endif
+
+#ifndef CF_IMPLICIT_BRIDGING_DISABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end")
+#else
+#define CF_IMPLICIT_BRIDGING_DISABLED
+#endif
+#endif
+
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
#endif
@@ -63,7 +79,13 @@ typedef const struct __CFString * CFStri
typedef const struct __CFAllocator * CFAllocatorRef;
extern const CFAllocatorRef kCFAllocatorDefault;
extern CFTypeRef CFRetain(CFTypeRef cf);
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
extern void CFRelease(CFTypeRef cf);
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
extern CFTypeRef CFMakeCollectable(CFTypeRef cf);
typedef struct {
}
@@ -204,15 +226,27 @@ typedef io_object_t io_iterator_t;
typedef io_object_t io_service_t;
typedef struct IONotificationPort * IONotificationPortRef;
typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator );
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching );
kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing );
-kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}}
+kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated));
+
+CF_IMPLICIT_BRIDGING_DISABLED
+ // expected-note {{'IOServiceAddNotification' declared here}}
kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification );
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
CFMutableDictionaryRef IOServiceMatching( const char * name ) CF_RETURNS_RETAINED;
CFMutableDictionaryRef IOServiceNameMatching( const char * name ) CF_RETURNS_RETAINED;
CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName ) CF_RETURNS_RETAINED;
CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path ) CF_RETURNS_RETAINED;
CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ) CF_RETURNS_RETAINED;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
typedef struct __DASession * DASessionRef;
extern DASessionRef DASessionCreate( CFAllocatorRef allocator ) CF_RETURNS_RETAINED;
typedef struct __DADisk * DADiskRef;
@@ -295,13 +329,25 @@ extern CGGradientRef CGGradientCreateWit
extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
CFArrayRef colors, const CGFloat locations[]) CF_RETURNS_RETAINED;
extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
extern void CGGradientRelease(CGGradientRef gradient);
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
typedef struct CGContext *CGContextRef;
extern void CGContextDrawLinearGradient(CGContextRef context,
CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
CGGradientDrawingOptions options);
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void) CF_RETURNS_RETAINED;
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
@interface NSMutableArray : NSObject
- (void)addObject:(id)object;
+ (instancetype)array;
@@ -395,8 +441,14 @@ CFDateRef f7() {
// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and
// has the word create.
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
CFDateRef MyDateCreate() CF_RETURNS_RETAINED;
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
CFDateRef f8() {
CFDateRef date = MyDateCreate(); // expected-warning{{leak}}
CFRetain(date);
@@ -463,8 +515,14 @@ void f11() {
// PR 3337: Handle functions declared using typedefs.
typedef CFTypeRef CREATEFUN();
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
CFTypeRef MyCreateFun() CF_RETURNS_RETAINED;
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
void f12() {
CFTypeRef o = MyCreateFun(); // expected-warning {{leak}}
}
@@ -944,8 +1002,14 @@ void IOServiceNameMatching_wrapper(const
IOServiceNameMatching(name); // expected-warning{{leak}}
}
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
CF_RETURNS_RETAINED CFDictionaryRef CreateDict();
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
@@ -1361,8 +1425,14 @@ void testattr3() {
}
void consume_ns(id NS_CONSUMED x);
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
void consume_cf(id CF_CONSUMED x);
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
void testattr4() {
TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning
consume_ns(x);
@@ -1562,7 +1632,13 @@ static void rdar_8724287(CFErrorRef erro
// <rdar://problem/9234108> - Make sure the model applies cf_consumed
// correctly in argument positions besides the first.
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
extern void *CFStringCreate(void) CF_RETURNS_RETAINED;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value);
void rdar_9234108() {
rdar_9234108_helper(0, CFStringCreate());
@@ -1903,8 +1979,14 @@ id makeCollectableNonLeak() {
void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
void testConsumeAndStopTracking() {
id retained = [@[] retain]; // +1
consumeAndStopTracking(retained, ^{}); // no-warning
@@ -1971,9 +2053,15 @@ void test_drain() {
// value as tracked, even if the object isn't a known CF type.
//===----------------------------------------------------------------------===//
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
MyCFType getCustom() __attribute__((cf_returns_not_retained));
MyCFType makeCustom() __attribute__((cf_returns_retained));
+CF_IMPLICIT_BRIDGING_DISABLED
+
+
void testCustomReturnsRetained() {
MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}}
}
@@ -2020,3 +2108,14 @@ void rdar13783514(xpc_connection_t conne
xpc_connection_set_context(connection, [[NSMutableArray alloc] init]);
xpc_connection_set_finalizer_f(connection, releaseAfterXPC);
} // no-warning
+
+
+CF_IMPLICIT_BRIDGING_ENABLED
+
+CFAttributedStringRef CFAttributedCreate(long attributes) CF_RETURNS_RETAINED;
+
+CF_IMPLICIT_BRIDGING_DISABLED
+
+CFTypeID CFGetTypeID(void) {
+ return 0;
+}
More information about the cfe-commits
mailing list