forked from OSchip/llvm-project
[analyzer] Re-apply r283093 "Add extra notes to ObjCDeallocChecker"
The parent commit (r283092) was reverted before and now finally landed. llvm-svn: 283660
This commit is contained in:
parent
2433b26176
commit
46209e1dd0
|
@ -107,6 +107,9 @@ class ObjCDeallocChecker
|
|||
std::unique_ptr<BugType> ExtraReleaseBugType;
|
||||
std::unique_ptr<BugType> MistakenDeallocBugType;
|
||||
|
||||
static constexpr const char *MsgDeclared = "Property is declared here";
|
||||
static constexpr const char *MsgSynthesized = "Property is synthesized here";
|
||||
|
||||
public:
|
||||
ObjCDeallocChecker();
|
||||
|
||||
|
@ -128,6 +131,9 @@ public:
|
|||
void checkEndFunction(CheckerContext &Ctx) const;
|
||||
|
||||
private:
|
||||
void addNoteForDecl(std::unique_ptr<BugReport> &BR, StringRef Msg,
|
||||
const Decl *D) const;
|
||||
|
||||
void diagnoseMissingReleases(CheckerContext &C) const;
|
||||
|
||||
bool diagnoseExtraRelease(SymbolRef ReleasedValue, const ObjCMethodCall &M,
|
||||
|
@ -489,6 +495,18 @@ ProgramStateRef ObjCDeallocChecker::checkPointerEscape(
|
|||
return State;
|
||||
}
|
||||
|
||||
/// Add an extra note piece describing a declaration that is important
|
||||
/// for understanding the bug report.
|
||||
void ObjCDeallocChecker::addNoteForDecl(std::unique_ptr<BugReport> &BR,
|
||||
StringRef Msg,
|
||||
const Decl *D) const {
|
||||
ASTContext &ACtx = D->getASTContext();
|
||||
SourceManager &SM = ACtx.getSourceManager();
|
||||
PathDiagnosticLocation Pos = PathDiagnosticLocation::createBegin(D, SM);
|
||||
if (Pos.isValid() && Pos.asLocation().isValid())
|
||||
BR->addNote(Msg, Pos, D->getSourceRange());
|
||||
}
|
||||
|
||||
/// Report any unreleased instance variables for the current instance being
|
||||
/// dealloced.
|
||||
void ObjCDeallocChecker::diagnoseMissingReleases(CheckerContext &C) const {
|
||||
|
@ -586,6 +604,9 @@ void ObjCDeallocChecker::diagnoseMissingReleases(CheckerContext &C) const {
|
|||
std::unique_ptr<BugReport> BR(
|
||||
new BugReport(*MissingReleaseBugType, OS.str(), ErrNode));
|
||||
|
||||
addNoteForDecl(BR, MsgDeclared, PropDecl);
|
||||
addNoteForDecl(BR, MsgSynthesized, PropImpl);
|
||||
|
||||
C.emitReport(std::move(BR));
|
||||
}
|
||||
|
||||
|
@ -689,11 +710,12 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue,
|
|||
);
|
||||
|
||||
const ObjCImplDecl *Container = getContainingObjCImpl(C.getLocationContext());
|
||||
OS << "The '" << *PropImpl->getPropertyIvarDecl()
|
||||
<< "' ivar in '" << *Container;
|
||||
const ObjCIvarDecl *IvarDecl = PropImpl->getPropertyIvarDecl();
|
||||
OS << "The '" << *IvarDecl << "' ivar in '" << *Container;
|
||||
|
||||
bool ReleasedByCIFilterDealloc = isReleasedByCIFilterDealloc(PropImpl);
|
||||
|
||||
if (isReleasedByCIFilterDealloc(PropImpl)) {
|
||||
if (ReleasedByCIFilterDealloc) {
|
||||
OS << "' will be released by '-[CIFilter dealloc]' but also released here";
|
||||
} else {
|
||||
OS << "' was synthesized for ";
|
||||
|
@ -710,6 +732,10 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue,
|
|||
new BugReport(*ExtraReleaseBugType, OS.str(), ErrNode));
|
||||
BR->addRange(M.getOriginExpr()->getSourceRange());
|
||||
|
||||
addNoteForDecl(BR, MsgDeclared, PropDecl);
|
||||
if (!ReleasedByCIFilterDealloc)
|
||||
addNoteForDecl(BR, MsgSynthesized, PropImpl);
|
||||
|
||||
C.emitReport(std::move(BR));
|
||||
|
||||
return true;
|
||||
|
|
|
@ -80,6 +80,9 @@
|
|||
|
||||
@interface MyPropertyClass1 : NSObject
|
||||
@property (copy) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClass1
|
||||
|
@ -93,6 +96,9 @@
|
|||
|
||||
@interface MyPropertyClass2 : NSObject
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClass2
|
||||
|
@ -108,10 +114,16 @@
|
|||
NSObject *_ivar;
|
||||
}
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClass3
|
||||
@synthesize ivar = _ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
- (void)dealloc
|
||||
{
|
||||
#if NON_ARC
|
||||
|
@ -125,6 +137,9 @@
|
|||
void (^_blockPropertyIvar)(void);
|
||||
}
|
||||
@property (copy) void (^blockProperty)(void);
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@property (copy) void (^blockProperty2)(void);
|
||||
@property (copy) void (^blockProperty3)(void);
|
||||
|
||||
|
@ -132,6 +147,9 @@
|
|||
|
||||
@implementation MyPropertyClass4
|
||||
@synthesize blockProperty = _blockPropertyIvar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
- (void)dealloc
|
||||
{
|
||||
#if NON_ARC
|
||||
|
@ -163,10 +181,16 @@
|
|||
NSObject *_ivar;
|
||||
}
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClassWithReturnInDealloc
|
||||
@synthesize ivar = _ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
- (void)dealloc
|
||||
{
|
||||
return;
|
||||
|
@ -182,12 +206,18 @@
|
|||
MyPropertyClassWithReleaseInOtherInstance *_other;
|
||||
}
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
|
||||
-(void)releaseIvars;
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClassWithReleaseInOtherInstance
|
||||
@synthesize ivar = _ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
|
||||
-(void)releaseIvars; {
|
||||
#if NON_ARC
|
||||
|
@ -208,10 +238,16 @@
|
|||
NSObject *_ivar;
|
||||
}
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation MyPropertyClassWithNeitherReturnNorSuperDealloc
|
||||
@synthesize ivar = _ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
|
@ -246,6 +282,9 @@
|
|||
BOOL _ivar1;
|
||||
}
|
||||
@property (retain) NSObject *ivar2;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation ClassWithControlFlowInRelease
|
||||
|
@ -287,6 +326,9 @@
|
|||
|
||||
@interface ClassWithNildOutIvar : NSObject
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation ClassWithNildOutIvar
|
||||
|
@ -305,6 +347,9 @@
|
|||
|
||||
@interface ClassWithUpdatedIvar : NSObject
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation ClassWithUpdatedIvar
|
||||
|
@ -349,6 +394,9 @@
|
|||
@property (retain) NSObject *propNilledOutInFunction;
|
||||
|
||||
@property (retain) NSObject *ivarNeverReleased;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
- (void)invalidateInMethod;
|
||||
@end
|
||||
|
||||
|
@ -425,6 +473,9 @@ void NilOutPropertyHelper(ClassWithDeallocHelpers *o) {
|
|||
|
||||
@interface ClassWhereSelfEscapesViaSynthesizedPropertyAccess : NSObject
|
||||
@property (retain) NSObject *ivar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@property (retain) NSObject *otherIvar;
|
||||
@end
|
||||
|
||||
|
@ -442,6 +493,9 @@ void NilOutPropertyHelper(ClassWithDeallocHelpers *o) {
|
|||
|
||||
@interface ClassWhereSelfEscapesViaCallToSystem : NSObject
|
||||
@property (retain) NSObject *ivar1;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@property (retain) NSObject *ivar2;
|
||||
@property (retain) NSObject *ivar3;
|
||||
@property (retain) NSObject *ivar4;
|
||||
|
@ -536,6 +590,9 @@ void ReleaseMe(id arg);
|
|||
|
||||
@interface SuperClassOfClassWithInlinedSuperDealloc : NSObject
|
||||
@property (retain) NSObject *propInSuper;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation SuperClassOfClassWithInlinedSuperDealloc
|
||||
|
@ -548,6 +605,9 @@ void ReleaseMe(id arg);
|
|||
|
||||
@interface ClassWithInlinedSuperDealloc : SuperClassOfClassWithInlinedSuperDealloc
|
||||
@property (retain) NSObject *propInSub;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation ClassWithInlinedSuperDealloc
|
||||
|
@ -605,6 +665,9 @@ void ReleaseMe(id arg);
|
|||
|
||||
@interface SuperClassOfClassThatEscapesBeforeInliningSuper : NSObject
|
||||
@property (retain) NSObject *propInSuper;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation SuperClassOfClassThatEscapesBeforeInliningSuper
|
||||
|
@ -794,6 +857,9 @@ __attribute__((objc_root_class))
|
|||
|
||||
@property(retain) NSObject *inputIvar;
|
||||
@property(retain) NSObject *nonInputIvar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@property(retain) NSObject *inputAutoSynthesizedIvar;
|
||||
@property(retain) NSObject *inputExplicitlySynthesizedToNonPrefixedIvar;
|
||||
@property(retain) NSObject *nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar;
|
||||
|
@ -803,6 +869,9 @@ __attribute__((objc_root_class))
|
|||
@implementation ImmediateSubCIFilter
|
||||
@synthesize inputIvar = inputIvar;
|
||||
@synthesize nonInputIvar = nonInputIvar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
@synthesize inputExplicitlySynthesizedToNonPrefixedIvar = notPrefixedButBackingPrefixedProperty;
|
||||
@synthesize nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar = inputPrefixedButBackingNonPrefixedProperty;
|
||||
|
||||
|
@ -841,6 +910,9 @@ __attribute__((objc_root_class))
|
|||
}
|
||||
|
||||
@property(retain) NSObject *inputIvar;
|
||||
#if NON_ARC
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation OverreleasingCIFilter
|
||||
|
|
|
@ -29,22 +29,22 @@
|
|||
id _nonPropertyIvar;
|
||||
}
|
||||
@property(retain) id X;
|
||||
@property(retain) id Y;
|
||||
@property(assign) id Z;
|
||||
@property(retain) id Y; // expected-note{{Property is declared here}}
|
||||
@property(assign) id Z; // expected-note{{Property is declared here}}
|
||||
@property(assign) id K;
|
||||
@property(weak) id L;
|
||||
@property(readonly) id N;
|
||||
@property(retain) id M;
|
||||
@property(weak) id P;
|
||||
@property(weak) id Q;
|
||||
@property(weak) id Q; // expected-note{{Property is declared here}}
|
||||
@property(retain) id R;
|
||||
@property(weak, readonly) id S;
|
||||
@property(weak, readonly) id S; // expected-note{{Property is declared here}}
|
||||
|
||||
@property(assign, readonly) id T; // Shadowed in class extension
|
||||
@property(assign) id U;
|
||||
|
||||
@property(retain) id V;
|
||||
@property(retain) id W;
|
||||
@property(retain) id W; // expected-note{{Property is declared here}}
|
||||
-(id) O;
|
||||
-(void) setO: (id) arg;
|
||||
@end
|
||||
|
@ -56,16 +56,16 @@
|
|||
|
||||
@implementation MyClass
|
||||
@synthesize X = _X;
|
||||
@synthesize Y = _Y;
|
||||
@synthesize Z = _Z;
|
||||
@synthesize Y = _Y; // expected-note{{Property is synthesized here}}
|
||||
@synthesize Z = _Z; // expected-note{{Property is synthesized here}}
|
||||
@synthesize K = _K;
|
||||
@synthesize L = _L;
|
||||
@synthesize N = _N;
|
||||
@synthesize M = _M;
|
||||
@synthesize Q = _Q;
|
||||
@synthesize Q = _Q; // expected-note{{Property is synthesized here}}
|
||||
@synthesize R = _R;
|
||||
@synthesize V = _V;
|
||||
@synthesize W = _W;
|
||||
@synthesize W = _W; // expected-note{{Property is synthesized here}}
|
||||
|
||||
-(id) O{ return 0; }
|
||||
-(void) setO:(id)arg { }
|
||||
|
|
|
@ -134,11 +134,17 @@ NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
|
|||
NSString *_name;
|
||||
}
|
||||
@property (retain) NSString * name;
|
||||
#if !__has_feature(objc_arc)
|
||||
// expected-note@-2 {{Property is declared here}}
|
||||
#endif
|
||||
@property (assign) id friend;
|
||||
@end
|
||||
|
||||
@implementation Person
|
||||
@synthesize name = _name;
|
||||
#if !__has_feature(objc_arc)
|
||||
// expected-note@-2 {{Property is synthesized here}}
|
||||
#endif
|
||||
|
||||
-(void)dealloc {
|
||||
#if !__has_feature(objc_arc)
|
||||
|
|
Loading…
Reference in New Issue