summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2016-10-03 08:03:51 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2016-10-03 08:03:51 +0000
commit918602df8dc137dfeb148315248751b68776c25d (patch)
tree8db2c2b8d8c216f938691515209582a77206f466 /clang/lib
parent9dceb11b2fd4c5e34b759d26ce3a63dbe3a80a77 (diff)
downloadbcm5719-llvm-918602df8dc137dfeb148315248751b68776c25d.tar.gz
bcm5719-llvm-918602df8dc137dfeb148315248751b68776c25d.zip
[analyzer] Add extra notes to ObjCDeallocChecker
The report is now highlighting instance variables and properties referenced by the warning message with the help of the extra notes feature recently introduced in r283092. Differential Revision: https://reviews.llvm.org/D24915 llvm-svn: 283093
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp32
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;
OpenPOWER on IntegriCloud