]> granicus.if.org Git - clang/commitdiff
[analyzer] Teach ObjCDeallocChecker about XCTestCase
authorDevin Coughlin <dcoughlin@apple.com>
Wed, 22 Jun 2016 17:03:10 +0000 (17:03 +0000)
committerDevin Coughlin <dcoughlin@apple.com>
Wed, 22 Jun 2016 17:03:10 +0000 (17:03 +0000)
Like with SenTestCase, subclasses of XCTestCase follow a "tear down" idiom to
release instance variables and so typically do not release ivars in -dealloc.
This commit applies the existing special casing for SenTestCase to XCTestCase
as well.

rdar://problem/25884696

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

lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
test/Analysis/DeallocMissingRelease.m

index bee9deadd07f71a098a0be862fafed5989e53673..50915f399a16d7c67fef9ccdf658055b039df624 100644 (file)
@@ -98,8 +98,9 @@ class ObjCDeallocChecker
                      check::PointerEscape,
                      check::PreStmt<ReturnStmt>> {
 
-  mutable IdentifierInfo *NSObjectII, *SenTestCaseII, *Block_releaseII,
-                         *CIFilterII;
+  mutable IdentifierInfo *NSObjectII, *SenTestCaseII, *XCTestCaseII,
+      *Block_releaseII, *CIFilterII;
+
   mutable Selector DeallocSel, ReleaseSel;
 
   std::unique_ptr<BugType> MissingReleaseBugType;
@@ -760,9 +761,9 @@ bool ObjCDeallocChecker::diagnoseMistakenDealloc(SymbolRef DeallocedValue,
   return true;
 }
 
-ObjCDeallocChecker::
-    ObjCDeallocChecker()
-    : NSObjectII(nullptr), SenTestCaseII(nullptr), CIFilterII(nullptr) {
+ObjCDeallocChecker::ObjCDeallocChecker()
+    : NSObjectII(nullptr), SenTestCaseII(nullptr), XCTestCaseII(nullptr),
+      CIFilterII(nullptr) {
 
   MissingReleaseBugType.reset(
       new BugType(this, "Missing ivar release (leak)",
@@ -784,6 +785,7 @@ void ObjCDeallocChecker::initIdentifierInfoAndSelectors(
 
   NSObjectII = &Ctx.Idents.get("NSObject");
   SenTestCaseII = &Ctx.Idents.get("SenTestCase");
+  XCTestCaseII = &Ctx.Idents.get("XCTestCase");
   Block_releaseII = &Ctx.Idents.get("_Block_release");
   CIFilterII = &Ctx.Idents.get("CIFilter");
 
@@ -1023,11 +1025,11 @@ bool ObjCDeallocChecker::classHasSeparateTeardown(
     if (II == NSObjectII)
       return false;
 
-    // FIXME: For now, ignore classes that subclass SenTestCase, as these don't
-    // need to implement -dealloc.  They implement tear down in another way,
-    // which we should try and catch later.
+    // FIXME: For now, ignore classes that subclass SenTestCase and XCTestCase,
+    // as these don't need to implement -dealloc.  They implement tear down in
+    // another way, which we should try and catch later.
     //  http://llvm.org/bugs/show_bug.cgi?id=3187
-    if (II == SenTestCaseII)
+    if (II == XCTestCaseII || II == SenTestCaseII)
       return true;
   }
 
index 01fcc6e7c8e74376b25c9588d8efcc334ad56c60..009e80151814e110f13c5b0bda1e835fd747666c 100644 (file)
@@ -723,6 +723,28 @@ struct SomeStruct {
 }
 @end
 
+@interface XCTestCase : NSObject {}
+@end
+
+@interface MyClassXCTest : XCTestCase
+@property (retain) NSObject *ivar;
+@end
+
+@implementation MyClassXCTest
+-(void)tearDown {
+#if NON_ARC
+  [_ivar release];
+#endif
+}
+
+-(void)dealloc; {
+#if NON_ARC
+  [super dealloc]; // no-warning
+#endif
+}
+@end
+
+
 __attribute__((objc_root_class))
 @interface NonNSObjectMissingDealloc
 @property (retain) NSObject *ivar;