]> granicus.if.org Git - clang/commitdiff
[analyzer] Check for NULL passed to CFAutorelease.
authorJordan Rose <jordan_rose@apple.com>
Sat, 21 Jun 2014 23:50:40 +0000 (23:50 +0000)
committerJordan Rose <jordan_rose@apple.com>
Sat, 21 Jun 2014 23:50:40 +0000 (23:50 +0000)
Patch by Sean McBride, tests adjusted by me.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211453 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
test/ARCMT/objcmt-arc-cf-annotations.m
test/ARCMT/objcmt-arc-cf-annotations.m.result
test/Analysis/diagnostics/undef-value-param.m
test/Analysis/retain-release.m

index d36679d706c8fd1c57460b572eea1ab3f09555b1..3fd55760bc5f52a6ae56b592f0cf97c9dfc4ac4a 100644 (file)
@@ -523,16 +523,17 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
 }
 
 //===----------------------------------------------------------------------===//
-// CFRetain/CFRelease/CFMakeCollectable checking for null arguments.
+// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments.
 //===----------------------------------------------------------------------===//
 
 namespace {
 class CFRetainReleaseChecker : public Checker< check::PreStmt<CallExpr> > {
   mutable std::unique_ptr<APIMisuse> BT;
-  mutable IdentifierInfo *Retain, *Release, *MakeCollectable;
+  mutable IdentifierInfo *Retain, *Release, *MakeCollectable, *Autorelease;
 public:
   CFRetainReleaseChecker()
-      : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr) {}
+      : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr),
+        Autorelease(nullptr) {}
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 };
 } // end anonymous namespace
@@ -554,13 +555,15 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
     Retain = &Ctx.Idents.get("CFRetain");
     Release = &Ctx.Idents.get("CFRelease");
     MakeCollectable = &Ctx.Idents.get("CFMakeCollectable");
+    Autorelease = &Ctx.Idents.get("CFAutorelease");
     BT.reset(new APIMisuse(
-        this, "null passed to CFRetain/CFRelease/CFMakeCollectable"));
+        this, "null passed to CF memory management function"));
   }
 
-  // Check if we called CFRetain/CFRelease/CFMakeCollectable.
+  // Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
   const IdentifierInfo *FuncII = FD->getIdentifier();
-  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable))
+  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable ||
+        FuncII == Autorelease))
     return;
 
   // FIXME: The rest of this just checks that the argument is non-null.
@@ -597,6 +600,8 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
       description = "Null pointer argument in call to CFRelease";
     else if (FuncII == MakeCollectable)
       description = "Null pointer argument in call to CFMakeCollectable";
+    else if (FuncII == Autorelease)
+      description = "Null pointer argument in call to CFAutorelease";
     else
       llvm_unreachable("impossible case");
 
index 1e063f6e7368abd9feef59f92b84512696acb240..c9a5b8215d10736475e8d70a6d9413b9063f2927 100644 (file)
@@ -528,38 +528,54 @@ void f15() {
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
index 75dda6ca4014a5972cbd36926cd00eb7be08a4bb..84bc43dcb5ca75fe153783562051c0e9bc9c45b8 100644 (file)
@@ -570,38 +570,54 @@ void f15() {
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
index e977acb70fd97de3734f30afbf1311d867f74e47..b0ce56caa348fa7c3f0e73f83cafcd59ae900bce 100644 (file)
@@ -542,7 +542,7 @@ static void CreateRefUndef(SCDynamicStoreRef *storeRef, unsigned x) {
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
index afe997bf5d403b7c35341bb5175e116c3e690bdc..6973f9bcd67df966a0614a842c022c8063f72d2c 100644 (file)
@@ -523,38 +523,54 @@ void f15() {
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+    break;
+  case 3:
+    CFAutorelease(p); // expected-warning{{Null pointer argument in call to CFAutorelease}}
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
@@ -9501,7 +9517,7 @@ id returnNSNull() {
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
@@ -9838,7 +9854,7 @@ id returnNSNull() {
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRetain</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>8</string>
@@ -10175,7 +10191,7 @@ id returnNSNull() {
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFMakeCollectable</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>11</string>