From 7acc3a36ef4f938fc1ad65e0ef494b01f6892463 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 9 Apr 2008 21:41:14 +0000 Subject: Major refactoring/cleanup of GRExprEngine, ExplodedGraph, and BugReporter. Bugs are now reported using a combination of "BugType" (previously BugDescription) and Bug "BugReport" objects, which are fed to BugReporter (which generates PathDiagnostics). This provides a far more modular way of registering bug types and plugging in diagnostics. GRExprEngine now owns its copy of GRCoreEngine, and is not owned by the ExplodedGraph. ExplodedGraph is no longer templated on the "checker", but instead on the state contained in the nodes. llvm-svn: 49453 --- clang/lib/Analysis/BugReporter.cpp | 76 ++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 40 deletions(-) (limited to 'clang/lib/Analysis/BugReporter.cpp') diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 66b1b04c9d0..c851696a301 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/PathSensitive/BugReporter.h" +#include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceLocation.h" #include "clang/AST/ASTContext.h" @@ -25,6 +26,9 @@ using namespace clang; BugReporter::~BugReporter() {} +BugType::~BugType() {} +BugReport::~BugReport() {} +ExplodedGraph& BugReporter::getGraph() { return Eng.getGraph(); } static inline Stmt* GetStmt(const ProgramPoint& P) { if (const PostStmt* PS = dyn_cast(&P)) { @@ -48,7 +52,7 @@ static inline Stmt* GetStmt(const CFGBlock* B) { PathDiagnosticPiece* -BugDescription::getEndPath(ASTContext& Ctx, ExplodedNode *N) const { +BugReport::getEndPath(ASTContext& Ctx, ExplodedNode *N) const { Stmt* S = GetStmt(N->getLocation()); @@ -56,7 +60,9 @@ BugDescription::getEndPath(ASTContext& Ctx, ExplodedNode *N) const { return NULL; FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager()); - PathDiagnosticPiece* P = new PathDiagnosticPiece(L, getDescription()); + + PathDiagnosticPiece* P = + new PathDiagnosticPiece(L, getDescription()); const SourceRange *Beg, *End; getRanges(Beg, End); @@ -74,34 +80,38 @@ BugDescription::getEndPath(ASTContext& Ctx, ExplodedNode *N) const { return P; } -void BugDescription::getRanges(const SourceRange*& beg, - const SourceRange*& end) const { +void BugReport::getRanges(const SourceRange*& beg, + const SourceRange*& end) const { beg = NULL; end = NULL; } -void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, - const BugDescription& B, - ExplodedGraph& G, - ExplodedNode* N, - BugReporterHelper** BegHelpers, - BugReporterHelper** EndHelpers) { - - if (PathDiagnosticPiece* Piece = B.getEndPath(Ctx,N)) +PathDiagnosticPiece* BugReport::VisitNode(ExplodedNode* N, + ExplodedNode* PrevN, + ExplodedGraph& G, + ASTContext& Ctx) { + return NULL; +} + +void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, + BugReport& R, + ExplodedNode* N) { + + if (PathDiagnosticPiece* Piece = R.getEndPath(Ctx,N)) PD.push_back(Piece); else return; SourceManager& SMgr = Ctx.getSourceManager(); - llvm::OwningPtr > GTrim(G.Trim(&N, &N+1)); + llvm::OwningPtr > GTrim(getGraph().Trim(&N, &N+1)); // Find the sink in the trimmed graph. // FIXME: Should we eventually have a sink iterator? ExplodedNode* NewN = 0; - for (ExplodedGraph::node_iterator + for (ExplodedGraph::node_iterator I = GTrim->nodes_begin(), E = GTrim->nodes_end(); I != E; ++I) { if (I->isSink()) { @@ -292,13 +302,8 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, } } else - for (BugReporterHelper** I = BegHelpers; I != EndHelpers; ++I) { - - PathDiagnosticPiece* piece = (*I)->VisitNode(N, NextNode, G, Ctx); - - if (piece) - PD.push_front(piece); - } + if (PathDiagnosticPiece* piece = R.VisitNode(N, NextNode, *GTrim, Ctx)) + PD.push_front(piece); } } @@ -318,39 +323,30 @@ bool BugReporter::IsCached(ExplodedNode* N) { return false; } -void BugReporter::EmitPathWarning(Diagnostic& Diag, - PathDiagnosticClient* PDC, - ASTContext& Ctx, - const BugDescription& B, - ExplodedGraph& G, - ExplodedNode* N, - BugReporterHelper** BegHelpers, - BugReporterHelper** EndHelpers) { +void BugReporter::EmitPathWarning(BugReport& R, ExplodedNode* N) { - if (!PDC) { - EmitWarning(Diag, Ctx, B, N); + if (!PD) { + EmitWarning(R, N); return; } if (IsCached(N)) return; - PathDiagnostic D(B.getName()); - GeneratePathDiagnostic(D, Ctx, B, G, N, BegHelpers, EndHelpers); + PathDiagnostic D(R.getName()); + GeneratePathDiagnostic(D, R, N); if (!D.empty()) - PDC->HandlePathDiagnostic(D); + PD->HandlePathDiagnostic(D); } -void BugReporter::EmitWarning(Diagnostic& Diag, ASTContext& Ctx, - const BugDescription& B, - ExplodedNode* N) { +void BugReporter::EmitWarning(BugReport& R, ExplodedNode* N) { if (IsCached(N)) return; std::ostringstream os; - os << "[CHECKER] " << B.getDescription(); + os << "[CHECKER] " << R.getDescription(); unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, os.str().c_str()); @@ -362,8 +358,8 @@ void BugReporter::EmitWarning(Diagnostic& Diag, ASTContext& Ctx, if (!S) return; - SourceRange R = S->getSourceRange(); + SourceRange Range = S->getSourceRange(); Diag.Report(FullSourceLoc(S->getLocStart(), Ctx.getSourceManager()), - ErrorDiag, NULL, 0, &R, 1); + ErrorDiag, NULL, 0, &Range, 1); } -- cgit v1.2.3