r262277 - [analyzer] Update CheckObjCDealloc diagnostic for missing -dealloc.

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 29 16:39:04 PST 2016


Author: dcoughlin
Date: Mon Feb 29 18:39:04 2016
New Revision: 262277

URL: http://llvm.org/viewvc/llvm-project?rev=262277&view=rev
Log:
[analyzer] Update CheckObjCDealloc diagnostic for missing -dealloc.

Update the diagnostic for classes missing -dealloc to mention an instance
variable that needs to be released.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
    cfe/trunk/test/Analysis/MissingDealloc.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=262277&r1=262276&r2=262277&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Mon Feb 29 18:39:04 2016
@@ -190,23 +190,27 @@ void ObjCDeallocChecker::checkASTDecl(co
   initIdentifierInfoAndSelectors(Mgr.getASTContext());
 
   const ObjCInterfaceDecl *ID = D->getClassInterface();
+  // If the class is known to have a lifecycle with a separate teardown method
+  // then it may not require a -dealloc method.
+  if (classHasSeparateTeardown(ID))
+    return;
 
   // Does the class contain any synthesized properties that are retainable?
   // If not, skip the check entirely.
-  bool containsRetainedSynthesizedProperty = false;
+  const ObjCPropertyImplDecl *PropImplRequiringRelease = nullptr;
+  bool HasOthers = false;
   for (const auto *I : D->property_impls()) {
     if (getDeallocReleaseRequirement(I) == ReleaseRequirement::MustRelease) {
-      containsRetainedSynthesizedProperty = true;
-      break;
+      if (!PropImplRequiringRelease)
+        PropImplRequiringRelease = I;
+      else {
+        HasOthers = true;
+        break;
+      }
     }
   }
 
-  if (!containsRetainedSynthesizedProperty)
-    return;
-
-  // If the class is known to have a lifecycle with a separate teardown method
-  // then it may not require a -dealloc method.
-  if (classHasSeparateTeardown(ID))
+  if (!PropImplRequiringRelease)
     return;
 
   const ObjCMethodDecl *MD = nullptr;
@@ -224,8 +228,12 @@ void ObjCDeallocChecker::checkASTDecl(co
 
     std::string Buf;
     llvm::raw_string_ostream OS(Buf);
-    OS << "Objective-C class '" << *D << "' lacks a 'dealloc' instance method";
+    OS << "'" << *D << "' lacks a 'dealloc' instance method but "
+       << "must release '" << *PropImplRequiringRelease->getPropertyIvarDecl()
+       << "'";
 
+    if (HasOthers)
+      OS << " and others";
     PathDiagnosticLocation DLoc =
         PathDiagnosticLocation::createBegin(D, BR.getSourceManager());
 

Modified: cfe/trunk/test/Analysis/MissingDealloc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/MissingDealloc.m?rev=262277&r1=262276&r2=262277&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/MissingDealloc.m (original)
+++ cfe/trunk/test/Analysis/MissingDealloc.m Mon Feb 29 18:39:04 2016
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.Dealloc -fblocks %s 2>&1 | FileCheck -check-prefix=CHECK %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc %s 2>&1 | FileCheck -check-prefix=CHECK-ARC -allow-empty '--implicit-check-not=error:' '--implicit-check-not=warning:' %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.Dealloc -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
+
+#define NON_ARC !__has_feature(objc_arc)
+
+// No diagnostics expected under ARC.
+#if !NON_ARC
+  // expected-no-diagnostics
+#endif
 
 typedef signed char BOOL;
 @protocol NSObject
@@ -51,7 +58,9 @@ typedef struct objc_selector *SEL;
 @property (copy) NSObject *ivar;
 @end
 
-// CHECK: MissingDealloc.m:[[@LINE+1]]:1: warning: Objective-C class 'MissingDeallocWithCopyProperty' lacks a 'dealloc' instance method
+#if NON_ARC
+// expected-warning at +2{{'MissingDeallocWithCopyProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
+#endif
 @implementation MissingDeallocWithCopyProperty
 @end
 
@@ -59,17 +68,32 @@ typedef struct objc_selector *SEL;
 @property (retain) NSObject *ivar;
 @end
 
-// CHECK: MissingDealloc.m:[[@LINE+1]]:1: warning: Objective-C class 'MissingDeallocWithRetainProperty' lacks a 'dealloc' instance method
+#if NON_ARC
+// expected-warning at +2{{'MissingDeallocWithRetainProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
+#endif
 @implementation MissingDeallocWithRetainProperty
 @end
 
+ at interface MissingDeallocWithMultipleProperties : NSObject
+ at property (retain) NSObject *ivar1;
+ at property (retain) NSObject *ivar2;
+ at end
+
+#if NON_ARC
+// expected-warning at +2{{'MissingDeallocWithMultipleProperties' lacks a 'dealloc' instance method but must release '_ivar1' and others}}
+#endif
+ at implementation MissingDeallocWithMultipleProperties
+ at end
+
 @interface MissingDeallocWithIVarAndRetainProperty : NSObject {
   NSObject *_ivar2;
 }
 @property (retain) NSObject *ivar1;
 @end
 
-// CHECK: MissingDealloc.m:[[@LINE+1]]:1: warning: Objective-C class 'MissingDeallocWithIVarAndRetainProperty' lacks a 'dealloc' instance method
+#if NON_ARC
+// expected-warning at +2{{'MissingDeallocWithIVarAndRetainProperty' lacks a 'dealloc' instance method but must release '_ivar1'}}
+#endif
 @implementation MissingDeallocWithIVarAndRetainProperty
 @end
 
@@ -77,7 +101,9 @@ typedef struct objc_selector *SEL;
 @property (readonly,retain) NSObject *ivar;
 @end
 
-// CHECK: MissingDealloc.m:[[@LINE+1]]:1: warning: Objective-C class 'MissingDeallocWithReadOnlyRetainedProperty' lacks a 'dealloc' instance method
+#if NON_ARC
+// expected-warning at +2{{'MissingDeallocWithReadOnlyRetainedProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
+#endif
 @implementation MissingDeallocWithReadOnlyRetainedProperty
 @end
 




More information about the cfe-commits mailing list