diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-02-04 23:49:09 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-02-04 23:49:09 +0000 |
commit | cf118d41f7930a18dce97416ef7834a62642f587 (patch) | |
tree | 6039374169ed1df174e825aac0b026fc6683d561 /lib/Analysis/GRExprEngine.cpp | |
parent | a9b66347bec984d1fd0378f85f092e2330344747 (diff) |
Overhaul BugReporter interface and implementation. The new interface cleans up
the ownership of BugTypes and BugReports. Now BugReports are owned by BugTypes,
and BugTypes are owned by the BugReporter object.
The major functionality change in this patch is that reports are not immediately
emitted by a call to BugReporter::EmitWarning (now called EmitReport), but
instead of queued up in report "equivalence classes". When
BugReporter::FlushReports() is called, it emits one diagnostic per report
equivalence class. This provides a nice cleanup with the caching of reports as
well as enables the BugReporter engine to select the "best" path for reporting a
path-sensitive bug based on all the locations in the ExplodedGraph that the same
bug could occur.
Along with this patch, Leaks are now coalesced into a common equivalence class
by their allocation site, and the "summary" diagnostic for leaks now reports the
allocation site as the location of the bug (this may later be augmented to also
provide an example location where the leak occurs).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63796 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 59 |
1 files changed, 13 insertions, 46 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index bb34763df7..ea2ae3d92b 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -69,22 +69,7 @@ public: MapTy::iterator I = M.find(key); M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second); } - - virtual void EmitWarnings(BugReporter& BR) { - llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited; - - for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) - for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){ - - GRSimpleAPICheck* check = *I; - - if (AlreadyVisited.count(check)) - continue; - - check->EmitWarnings(BR); - } - } - + virtual bool Audit(NodeTy* N, GRStateManager& VMgr) { Stmt* S = cast<PostStmt>(N->getLocation()).getStmt(); void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass()); @@ -115,7 +100,8 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) { GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, - LiveVariables& L, bool purgeDead, + LiveVariables& L, BugReporterData& BRD, + bool purgeDead, StoreManagerCreator SMC, ConstraintManagerCreator CMC) : CoreEngine(cfg, CD, Ctx, *this), @@ -127,13 +113,11 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), - PurgeDead(purgeDead){} + PurgeDead(purgeDead), + BR(BRD, *this) {} GRExprEngine::~GRExprEngine() { - for (BugTypeSet::iterator I = BugTypes.begin(), E = BugTypes.end(); I!=E; ++I) - delete *I; - - + BR.FlushReports(); delete [] NSExceptionInstanceRaiseSelectors; } @@ -164,22 +148,9 @@ struct VISIBILITY_HIDDEN SaveOr { bool old_value; }; - -void GRExprEngine::EmitWarnings(BugReporterData& BRData) { - for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){ - GRBugReporter BR(BRData, *this); - (*I)->EmitWarnings(BR); - } - - if (BatchAuditor) { - GRBugReporter BR(BRData, *this); - BatchAuditor->EmitWarnings(BR); - } -} - void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) { StateMgr.TF = tf; - tf->RegisterChecks(*this); + tf->RegisterChecks(getBugReporter()); tf->RegisterPrinters(getStateManager().Printers); } @@ -2918,7 +2889,7 @@ void GRExprEngine::ViewGraph(bool trim) { if (trim) { std::vector<NodeTy*> Src; - // Fixme: Migrate over to the new way of adding nodes. + // FIXME: Migrate over to the new way of adding nodes. AddSources(Src, null_derefs_begin(), null_derefs_end()); AddSources(Src, undef_derefs_begin(), undef_derefs_end()); AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end()); @@ -2927,10 +2898,8 @@ void GRExprEngine::ViewGraph(bool trim) { AddSources(Src, undef_arg_begin(), undef_arg_end()); AddSources(Src, undef_branches_begin(), undef_branches_end()); - // The new way. - for (BugTypeSet::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I) - (*I)->GetErrorNodes(Src); - + // FIXME: Enhance BugReporter to have a clean way to query if a node + // is involved in an error... and what kind. ViewGraph(&Src[0], &Src[0]+Src.size()); } @@ -2951,14 +2920,12 @@ void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) { GraphPrintCheckerState = this; GraphPrintSourceManager = &getContext().getSourceManager(); - GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End); + std::auto_ptr<GRExprEngine::GraphTy> TrimmedG(G.Trim(Beg, End).first); - if (!TrimmedG) + if (!TrimmedG.get()) llvm::cerr << "warning: Trimmed ExplodedGraph is empty.\n"; - else { + else llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine"); - delete TrimmedG; - } GraphPrintCheckerState = NULL; GraphPrintSourceManager = NULL; |