aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/CoreEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/CoreEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp59
1 files changed, 32 insertions, 27 deletions
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index b09b2c2ddfab..4623c358a9e2 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -12,8 +12,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "CoreEngine"
-
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtCXX.h"
@@ -26,6 +24,8 @@
using namespace clang;
using namespace ento;
+#define DEBUG_TYPE "CoreEngine"
+
STATISTIC(NumSteps,
"The # of steps executed.");
STATISTIC(NumReachedMaxSteps,
@@ -43,22 +43,22 @@ namespace {
class DFS : public WorkList {
SmallVector<WorkListUnit,20> Stack;
public:
- virtual bool hasWork() const {
+ bool hasWork() const override {
return !Stack.empty();
}
- virtual void enqueue(const WorkListUnit& U) {
+ void enqueue(const WorkListUnit& U) override {
Stack.push_back(U);
}
- virtual WorkListUnit dequeue() {
+ WorkListUnit dequeue() override {
assert (!Stack.empty());
const WorkListUnit& U = Stack.back();
Stack.pop_back(); // This technically "invalidates" U, but we are fine.
return U;
}
-
- virtual bool visitItemsInWorkList(Visitor &V) {
+
+ bool visitItemsInWorkList(Visitor &V) override {
for (SmallVectorImpl<WorkListUnit>::iterator
I = Stack.begin(), E = Stack.end(); I != E; ++I) {
if (V.visit(*I))
@@ -71,21 +71,21 @@ public:
class BFS : public WorkList {
std::deque<WorkListUnit> Queue;
public:
- virtual bool hasWork() const {
+ bool hasWork() const override {
return !Queue.empty();
}
- virtual void enqueue(const WorkListUnit& U) {
+ void enqueue(const WorkListUnit& U) override {
Queue.push_back(U);
}
- virtual WorkListUnit dequeue() {
+ WorkListUnit dequeue() override {
WorkListUnit U = Queue.front();
Queue.pop_front();
return U;
}
-
- virtual bool visitItemsInWorkList(Visitor &V) {
+
+ bool visitItemsInWorkList(Visitor &V) override {
for (std::deque<WorkListUnit>::iterator
I = Queue.begin(), E = Queue.end(); I != E; ++I) {
if (V.visit(*I))
@@ -109,18 +109,18 @@ namespace {
std::deque<WorkListUnit> Queue;
SmallVector<WorkListUnit,20> Stack;
public:
- virtual bool hasWork() const {
+ bool hasWork() const override {
return !Queue.empty() || !Stack.empty();
}
- virtual void enqueue(const WorkListUnit& U) {
+ void enqueue(const WorkListUnit& U) override {
if (U.getNode()->getLocation().getAs<BlockEntrance>())
Queue.push_front(U);
else
Stack.push_back(U);
}
- virtual WorkListUnit dequeue() {
+ WorkListUnit dequeue() override {
// Process all basic blocks to completion.
if (!Stack.empty()) {
const WorkListUnit& U = Stack.back();
@@ -135,7 +135,7 @@ namespace {
Queue.pop_front();
return U;
}
- virtual bool visitItemsInWorkList(Visitor &V) {
+ bool visitItemsInWorkList(Visitor &V) override {
for (SmallVectorImpl<WorkListUnit>::iterator
I = Stack.begin(), E = Stack.end(); I != E; ++I) {
if (V.visit(*I))
@@ -192,9 +192,9 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
if (!InitState)
// Generate the root.
- generateNode(StartLoc, SubEng.getInitialState(L), 0);
+ generateNode(StartLoc, SubEng.getInitialState(L), nullptr);
else
- generateNode(StartLoc, InitState, 0);
+ generateNode(StartLoc, InitState, nullptr);
}
// Check if we have a steps limit
@@ -532,11 +532,16 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N,
return;
}
+ if ((*Block)[Idx].getKind() == CFGElement::NewAllocator) {
+ WList->enqueue(N, Block, Idx+1);
+ return;
+ }
+
// At this point, we know we're processing a normal statement.
CFGStmt CS = (*Block)[Idx].castAs<CFGStmt>();
PostStmt Loc(CS.getStmt(), N->getLocationContext());
- if (Loc == N->getLocation()) {
+ if (Loc == N->getLocation().withTag(nullptr)) {
// Note: 'N' should be a fresh node because otherwise it shouldn't be
// a member of Deferred.
WList->enqueue(N, Block, Idx+1);
@@ -562,7 +567,7 @@ ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N) {
bool isNew;
ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew);
Node->addPredecessor(N, *G);
- return isNew ? Node : 0;
+ return isNew ? Node : nullptr;
}
@@ -611,7 +616,7 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
Frontier.erase(FromN);
if (!IsNew)
- return 0;
+ return nullptr;
if (!MarkAsSink)
Frontier.Add(N);
@@ -635,7 +640,7 @@ ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State,
ExplodedNode *NodePred) {
// If the branch has been marked infeasible we should not generate a node.
if (!isFeasible(branch))
- return NULL;
+ return nullptr;
ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
NodePred->getLocationContext());
@@ -654,7 +659,7 @@ IndirectGotoNodeBuilder::generateNode(const iterator &I,
Succ->addPredecessor(Pred, *Eng.G);
if (!IsNew)
- return 0;
+ return nullptr;
if (!IsSink)
Eng.WList->enqueue(Succ);
@@ -673,7 +678,7 @@ SwitchNodeBuilder::generateCaseStmtNode(const iterator &I,
false, &IsNew);
Succ->addPredecessor(Pred, *Eng.G);
if (!IsNew)
- return 0;
+ return nullptr;
Eng.WList->enqueue(Succ);
return Succ;
@@ -690,8 +695,8 @@ SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St,
// Sanity check for default blocks that are unreachable and not caught
// by earlier stages.
if (!DefaultBlock)
- return NULL;
-
+ return nullptr;
+
bool IsNew;
ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
Pred->getLocationContext()), St,
@@ -699,7 +704,7 @@ SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St,
Succ->addPredecessor(Pred, *Eng.G);
if (!IsNew)
- return 0;
+ return nullptr;
if (!IsSink)
Eng.WList->enqueue(Succ);