diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2016-10-08 10:53:00 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2016-10-08 10:53:00 +0000 |
commit | 46209e1dd08be5dfb5171648430196881a1fbc09 (patch) | |
tree | e67d4db305a30abe573e4e647b72dc86481dc071 /clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp | |
parent | 2433b26176f2e390f0771e4bb88cc73b6b18d817 (diff) | |
download | bcm5719-llvm-46209e1dd08be5dfb5171648430196881a1fbc09.tar.gz bcm5719-llvm-46209e1dd08be5dfb5171648430196881a1fbc09.zip |
[analyzer] Re-apply r283093 "Add extra notes to ObjCDeallocChecker"
The parent commit (r283092) was reverted before and now finally landed.
llvm-svn: 283660
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index ffb0adc8d63..8fd36b82866 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -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; |