зеркало из https://github.com/microsoft/clang.git
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
This commit is contained in:
Родитель
9b823e8e1c
Коммит
bc42c533e7
|
@ -285,7 +285,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B,
|
||||
bool hasWorkRemaining) {}
|
||||
GRExprEngine &Eng) {}
|
||||
};
|
||||
} // end clang namespace
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -33,8 +33,9 @@ namespace {
|
|||
class UnreachableCodeChecker : public CheckerVisitor<UnreachableCodeChecker> {
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче