From bc42c533e7d3d946704a49e242939dd232f33072 Mon Sep 17 00:00:00 2001 From: Tom Care Date: Tue, 3 Aug 2010 01:55:07 +0000 Subject: [PATCH] Changed GRExprEngine to pass down a reference to itself when checkers are doing postanalysis. This allows the checker to gather information about the state of the engine when it has finished. - Exposed the worklist and BlockAborted flag in GRCoreEngine - Changed postanalysis checkers to use the new infrastructure git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110095 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Checker/PathSensitive/Checker.h | 2 +- include/clang/Checker/PathSensitive/GRCoreEngine.h | 6 ++++++ include/clang/Checker/PathSensitive/GRExprEngine.h | 8 ++++++++ lib/Checker/GRExprEngine.cpp | 2 +- lib/Checker/IdempotentOperationChecker.cpp | 7 +++---- lib/Checker/UnreachableCodeChecker.cpp | 9 +++++---- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h index b439205edd..81f151b89d 100644 --- a/include/clang/Checker/PathSensitive/Checker.h +++ b/include/clang/Checker/PathSensitive/Checker.h @@ -285,7 +285,7 @@ public: } virtual void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, - bool hasWorkRemaining) {} + GRExprEngine &Eng) {} }; } // end clang namespace diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h index 90f6979b53..dbef757826 100644 --- a/include/clang/Checker/PathSensitive/GRCoreEngine.h +++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h @@ -158,6 +158,12 @@ public: void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, const GRState *InitState, ExplodedNodeSet &Dst); + + // Functions for external checking of whether we have unfinished work + bool wasBlockAborted() const { return BlockAborted; } + bool hasWorkRemaining() const { return BlockAborted || WList->hasWork(); } + + GRWorkList *getWorkList() const { return WList; } }; class GRStmtNodeBuilder { diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index 8f01ab9f7c..ffdf9de049 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -236,6 +236,14 @@ public: SymbolManager& getSymbolManager() { return SymMgr; } const SymbolManager& getSymbolManager() const { return SymMgr; } + // Functions for external checking of whether we have unfinished work + bool wasBlockAborted() const { return CoreEngine.wasBlockAborted(); } + bool hasWorkRemaining() const { + return wasBlockAborted() || getWorkList()->hasWork(); + } + + GRWorkList *getWorkList() const { return CoreEngine.getWorkList(); } + protected: const GRState* GetState(ExplodedNode* N) { return N == EntryNode ? CleanedState : N->getState(); diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 9ee723eb7c..328dacfe90 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -518,7 +518,7 @@ const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond, void GRExprEngine::ProcessEndWorklist(bool hasWorkRemaining) { for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end(); I != E; ++I) { - I->second->VisitEndAnalysis(G, BR, hasWorkRemaining); + I->second->VisitEndAnalysis(G, BR, *this); } } diff --git a/lib/Checker/IdempotentOperationChecker.cpp b/lib/Checker/IdempotentOperationChecker.cpp index 267e747928..26b018e54b 100644 --- a/lib/Checker/IdempotentOperationChecker.cpp +++ b/lib/Checker/IdempotentOperationChecker.cpp @@ -65,8 +65,7 @@ class IdempotentOperationChecker public: static void *getTag(); void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B); - void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, - bool hasWorkRemaining); + void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, GRExprEngine &Eng); private: // Our assumption about a particular operation. @@ -293,9 +292,9 @@ void IdempotentOperationChecker::PreVisitBinaryOperator( void IdempotentOperationChecker::VisitEndAnalysis(ExplodedGraph &G, BugReporter &BR, - bool hasWorkRemaining) { + GRExprEngine &Eng) { // If there is any work remaining we cannot be 100% sure about our warnings - if (hasWorkRemaining) + if (Eng.hasWorkRemaining()) return; // Iterate over the hash to see if we have any paths with definite diff --git a/lib/Checker/UnreachableCodeChecker.cpp b/lib/Checker/UnreachableCodeChecker.cpp index e95e6a832d..e3d758f20a 100644 --- a/lib/Checker/UnreachableCodeChecker.cpp +++ b/lib/Checker/UnreachableCodeChecker.cpp @@ -33,8 +33,9 @@ namespace { class UnreachableCodeChecker : public CheckerVisitor { public: static void *getTag(); - void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, - bool hasWorkRemaining); + void VisitEndAnalysis(ExplodedGraph &G, + BugReporter &B, + GRExprEngine &Eng); private: typedef bool (*ExplodedNodeHeuristic)(const ExplodedNode &EN); @@ -60,9 +61,9 @@ void clang::RegisterUnreachableCodeChecker(GRExprEngine &Eng) { void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, - bool hasWorkRemaining) { + GRExprEngine &Eng) { // Bail out if we didn't cover all paths - if (hasWorkRemaining) + if (Eng.hasWorkRemaining()) return; CFG *C = 0; -- 2.40.0