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