зеркало из https://github.com/microsoft/clang-1.git
Modified BugReport::getEndPath() to handle the case where end path is at
the exit block of the CFG. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49880 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
989d519636
Коммит
bd7efa8ca2
|
@ -63,7 +63,8 @@ public:
|
||||||
return getBugType().getDescription();
|
return getBugType().getDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual PathDiagnosticPiece* getEndPath(ASTContext& Ctx) const;
|
virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
|
||||||
|
ExplodedNode<ValueState>* N) const;
|
||||||
|
|
||||||
virtual FullSourceLoc getLocation(SourceManager& Mgr);
|
virtual FullSourceLoc getLocation(SourceManager& Mgr);
|
||||||
|
|
||||||
|
@ -124,6 +125,8 @@ public:
|
||||||
|
|
||||||
GRExprEngine& getEngine() { return Eng; }
|
GRExprEngine& getEngine() { return Eng; }
|
||||||
|
|
||||||
|
CFG& getCFG() { return getGraph().getCFG(); }
|
||||||
|
|
||||||
void EmitPathWarning(BugReport& R);
|
void EmitPathWarning(BugReport& R);
|
||||||
|
|
||||||
void EmitWarning(BugReport& R);
|
void EmitWarning(BugReport& R);
|
||||||
|
|
|
@ -56,14 +56,43 @@ Stmt* BugReport::getStmt() const {
|
||||||
return N ? GetStmt(N->getLocation()) : NULL;
|
return N ? GetStmt(N->getLocation()) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathDiagnosticPiece* BugReport::getEndPath(ASTContext& Ctx) const {
|
static inline ExplodedNode<ValueState>*
|
||||||
|
GetNextNode(ExplodedNode<ValueState>* N) {
|
||||||
|
return N->pred_empty() ? NULL : *(N->pred_begin());
|
||||||
|
}
|
||||||
|
|
||||||
Stmt* S = getStmt();
|
|
||||||
|
static Stmt* GetLastStmt(ExplodedNode<ValueState>* N) {
|
||||||
|
assert (isa<BlockEntrance>(N->getLocation()));
|
||||||
|
|
||||||
|
for (N = GetNextNode(N); N; N = GetNextNode(N)) {
|
||||||
|
|
||||||
|
ProgramPoint P = N->getLocation();
|
||||||
|
|
||||||
|
if (PostStmt* PS = dyn_cast<PostStmt>(&P))
|
||||||
|
return PS->getStmt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PathDiagnosticPiece*
|
||||||
|
BugReport::getEndPath(BugReporter& BR,
|
||||||
|
ExplodedNode<ValueState>* EndPathNode) const {
|
||||||
|
|
||||||
|
ProgramPoint ProgP = EndPathNode->getLocation();
|
||||||
|
Stmt *S = NULL;
|
||||||
|
|
||||||
|
if (BlockEntrance* BE = dyn_cast<BlockEntrance>(&ProgP))
|
||||||
|
if (BE->getBlock() == &BR.getCFG().getExit())
|
||||||
|
S = GetLastStmt(EndPathNode);
|
||||||
|
if (!S)
|
||||||
|
S = GetStmt(ProgP);
|
||||||
|
|
||||||
if (!S)
|
if (!S)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager());
|
FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
|
||||||
|
|
||||||
PathDiagnosticPiece* P =
|
PathDiagnosticPiece* P =
|
||||||
new PathDiagnosticPiece(L, getDescription());
|
new PathDiagnosticPiece(L, getDescription());
|
||||||
|
@ -114,16 +143,8 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||||
BugReport& R) {
|
BugReport& R) {
|
||||||
|
|
||||||
ExplodedNode<ValueState>* N = R.getEndNode();
|
ExplodedNode<ValueState>* N = R.getEndNode();
|
||||||
|
|
||||||
assert (N && "Path diagnostic requires a ExplodedNode.");
|
assert (N && "Path diagnostic requires a ExplodedNode.");
|
||||||
|
|
||||||
if (PathDiagnosticPiece* Piece = R.getEndPath(Ctx))
|
|
||||||
PD.push_back(Piece);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
SourceManager& SMgr = Ctx.getSourceManager();
|
|
||||||
|
|
||||||
llvm::OwningPtr<ExplodedGraph<ValueState> > GTrim(getGraph().Trim(&N, &N+1));
|
llvm::OwningPtr<ExplodedGraph<ValueState> > GTrim(getGraph().Trim(&N, &N+1));
|
||||||
|
|
||||||
// Find the sink in the trimmed graph.
|
// Find the sink in the trimmed graph.
|
||||||
|
@ -145,14 +166,21 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||||
|
|
||||||
N = NewN;
|
N = NewN;
|
||||||
|
|
||||||
|
if (PathDiagnosticPiece* Piece = R.getEndPath(*this, N))
|
||||||
|
PD.push_back(Piece);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
ExplodedNode<ValueState>* NextNode = N->pred_empty()
|
ExplodedNode<ValueState>* NextNode = N->pred_empty()
|
||||||
? NULL : *(N->pred_begin());
|
? NULL : *(N->pred_begin());
|
||||||
|
|
||||||
|
SourceManager& SMgr = Ctx.getSourceManager();
|
||||||
|
|
||||||
while (NextNode) {
|
while (NextNode) {
|
||||||
|
|
||||||
ExplodedNode<ValueState>* LastNode = N;
|
ExplodedNode<ValueState>* LastNode = N;
|
||||||
N = NextNode;
|
N = NextNode;
|
||||||
NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
|
NextNode = GetNextNode(N);
|
||||||
|
|
||||||
ProgramPoint P = N->getLocation();
|
ProgramPoint P = N->getLocation();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче