forked from OSchip/llvm-project
Added line number diagnostics to indicate the allocation site of the leaked object.
llvm-svn: 50553
This commit is contained in:
parent
fabfb4677d
commit
1097b4c61f
|
@ -143,6 +143,8 @@ public:
|
|||
|
||||
ASTContext& getContext() { return Ctx; }
|
||||
|
||||
SourceManager& getSourceManager() { return Ctx.getSourceManager(); }
|
||||
|
||||
ExplodedGraph<ValueState>& getGraph();
|
||||
|
||||
GRExprEngine& getEngine() { return Eng; }
|
||||
|
|
|
@ -112,10 +112,8 @@ BugReport::getEndPath(BugReporter& BR,
|
|||
if (!S)
|
||||
return NULL;
|
||||
|
||||
FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
|
||||
|
||||
PathDiagnosticPiece* P =
|
||||
new PathDiagnosticPiece(L, getDescription());
|
||||
FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
|
||||
PathDiagnosticPiece* P = new PathDiagnosticPiece(L, getDescription());
|
||||
|
||||
const SourceRange *Beg, *End;
|
||||
getRanges(BR, Beg, End);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "GRSimpleVals.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Analysis/PathSensitive/ValueState.h"
|
||||
#include "clang/Analysis/PathDiagnostic.h"
|
||||
#include "clang/Analysis/LocalCheckers.h"
|
||||
|
@ -1446,7 +1447,7 @@ namespace {
|
|||
|
||||
CFRefCount& getTF() { return TF; }
|
||||
|
||||
virtual bool ReportRanges() const { return true; }
|
||||
virtual bool isLeak() const { return false; }
|
||||
};
|
||||
|
||||
class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug {
|
||||
|
@ -1494,7 +1495,7 @@ namespace {
|
|||
|
||||
virtual void EmitWarnings(BugReporter& BR);
|
||||
virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
|
||||
virtual bool ReportRanges() const { return false; }
|
||||
virtual bool isLeak() const { return true; }
|
||||
};
|
||||
|
||||
//===---------===//
|
||||
|
@ -1519,7 +1520,7 @@ namespace {
|
|||
virtual void getRanges(BugReporter& BR, const SourceRange*& beg,
|
||||
const SourceRange*& end) {
|
||||
|
||||
if (getBugType().ReportRanges())
|
||||
if (getBugType().isLeak())
|
||||
RangedBugReport::getRanges(BR, beg, end);
|
||||
else {
|
||||
beg = 0;
|
||||
|
@ -1527,6 +1528,9 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
|
||||
ExplodedNode<ValueState>* N);
|
||||
|
||||
virtual std::pair<const char**,const char**> getExtraDescriptiveText();
|
||||
|
||||
virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
|
||||
|
@ -1699,6 +1703,52 @@ PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode<ValueState>* N,
|
|||
return P;
|
||||
}
|
||||
|
||||
PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
|
||||
ExplodedNode<ValueState>* N) {
|
||||
|
||||
if (!getBugType().isLeak())
|
||||
return RangedBugReport::getEndPath(BR, N);
|
||||
|
||||
// We are a leak. Walk up the graph to get to the first node where the
|
||||
// symbol appeared.
|
||||
|
||||
ExplodedNode<ValueState>* Last = N;
|
||||
typedef CFRefCount::RefBindings RefBindings;
|
||||
|
||||
// Find the first node that referred to the tracked symbol.
|
||||
|
||||
while (N) {
|
||||
ValueState* St = N->getState();
|
||||
RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
|
||||
|
||||
if (!B.SlimFind(Sym))
|
||||
break;
|
||||
|
||||
Last = N;
|
||||
N = N->pred_empty() ? NULL : *(N->pred_begin());
|
||||
}
|
||||
|
||||
// Get the location.
|
||||
|
||||
assert (Last);
|
||||
Stmt* FirstStmt = cast<PostStmt>(Last->getLocation()).getStmt();
|
||||
|
||||
unsigned Line =
|
||||
BR.getSourceManager().getLogicalLineNumber(FirstStmt->getLocStart());
|
||||
|
||||
// FIXME: Also get the name of the variable.
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Object allocated on line " << Line << " is leaked.";
|
||||
|
||||
Stmt* S = getStmt(BR);
|
||||
assert (S);
|
||||
FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
|
||||
PathDiagnosticPiece* P = new PathDiagnosticPiece(L, os.str());
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
void UseAfterRelease::EmitWarnings(BugReporter& BR) {
|
||||
|
||||
for (CFRefCount::use_after_iterator I = TF.use_after_begin(),
|
||||
|
|
Loading…
Reference in New Issue