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@+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@+2{{'MissingDeallocWithRetainProperty' lacks a 'dealloc' instance method but must release '_ivar'}} +#endif @implementation MissingDeallocWithRetainProperty @end +@interface MissingDeallocWithMultipleProperties : NSObject +@property (retain) NSObject *ivar1; +@property (retain) NSObject *ivar2; +@end + +#if NON_ARC +// expected-warning@+2{{'MissingDeallocWithMultipleProperties' lacks a 'dealloc' instance method but must release '_ivar1' and others}} +#endif +@implementation MissingDeallocWithMultipleProperties +@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@+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@+2{{'MissingDeallocWithReadOnlyRetainedProperty' lacks a 'dealloc' instance method but must release '_ivar'}} +#endif @implementation MissingDeallocWithReadOnlyRetainedProperty @end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits