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