[cfe-commits] r96539 - in /cfe/trunk: lib/Checker/CFRefCount.cpp test/Analysis/retain-release.m

Ted Kremenek kremenek at apple.com
Wed Feb 17 16:06:12 PST 2010


Author: kremenek
Date: Wed Feb 17 18:06:12 2010
New Revision: 96539

URL: http://llvm.org/viewvc/llvm-project?rev=96539&view=rev
Log:
Recognize attributes ns_returns_not_retained and cf_returns_not_retained
in the static analyzer.

Modified:
    cfe/trunk/lib/Checker/CFRefCount.cpp
    cfe/trunk/test/Analysis/retain-release.m

Modified: cfe/trunk/lib/Checker/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CFRefCount.cpp?rev=96539&r1=96538&r2=96539&view=diff

==============================================================================
--- cfe/trunk/lib/Checker/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Checker/CFRefCount.cpp Wed Feb 17 18:06:12 2010
@@ -1222,6 +1222,12 @@
     else if (FD->getAttr<CFReturnsRetainedAttr>()) {
       Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     }
+    else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+    }
+    else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+    }
   }
   else if (RetTy->getAs<PointerType>()) {
     if (FD->getAttr<CFReturnsRetainedAttr>()) {
@@ -1244,6 +1250,10 @@
       Summ.setRetEffect(ObjCAllocRetE);
       return;
     }
+    if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      return;
+    }
 
     isTrackedLoc = true;
   }
@@ -1251,8 +1261,12 @@
   if (!isTrackedLoc)
     isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL;
 
-  if (isTrackedLoc && MD->getAttr<CFReturnsRetainedAttr>())
-    Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+  if (isTrackedLoc) {
+    if (MD->getAttr<CFReturnsRetainedAttr>())
+      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+    else if (MD->getAttr<CFReturnsNotRetainedAttr>())
+      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+  }
 }
 
 RetainSummary*

Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=96539&r1=96538&r2=96539&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Wed Feb 17 18:06:12 2010
@@ -7,6 +7,12 @@
 #if __has_feature(attribute_cf_returns_retained)
 #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 #endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
@@ -1188,6 +1194,8 @@
 - (NSString*) returnsAnOwnedString  NS_RETURNS_RETAINED; // no-warning
 - (NSString*) returnsAnOwnedCFString  CF_RETURNS_RETAINED; // no-warning
 - (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
+- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
+- (NSString*) newStringNoAttr;
 - (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
 @end
 
@@ -1201,9 +1209,16 @@
   NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
 }
 
+void test_attr1c(TestOwnershipAttr *X) {
+  NSString *str = [X newString]; // no-warning
+  NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}}
+}
+
 @interface MyClassTestCFAttr : NSObject {}
 - (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;
 - (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED;
+- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED;
+- (CFDateRef) newCFRetainedAsCFNoAttr;
 - (NSDate*) alsoReturnsRetained;
 - (CFDateRef) alsoReturnsRetainedAsCF;
 - (NSDate*) returnsNSRetained NS_RETURNS_RETAINED;
@@ -1223,6 +1238,13 @@
   return returnsRetainedCFDate(); // No leak.
 }
 
+- (CFDateRef) newCFRetainedAsCF {
+  return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease];
+}
+
+- (CFDateRef) newCFRetainedAsCFNoAttr {
+  return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
 
 - (NSDate*) alsoReturnsRetained {
   return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}





More information about the cfe-commits mailing list