aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExplodedGraph.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index 160925b08f..bb0abfa965 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -15,6 +15,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/ParentMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -47,6 +48,13 @@ void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) {
typedef std::vector<ExplodedNode*> NodeList;
static inline NodeList*& getNodeList(void *&p) { return (NodeList*&) p; }
+static const unsigned CounterTop = 1000;
+
+ExplodedGraph::ExplodedGraph()
+ : NumNodes(0), recentlyAllocatedNodes(0),
+ freeNodes(0), reclaimNodes(false),
+ reclaimCounter(CounterTop) {}
+
ExplodedGraph::~ExplodedGraph() {
if (reclaimNodes) {
delete getNodeList(recentlyAllocatedNodes);
@@ -61,6 +69,15 @@ ExplodedGraph::~ExplodedGraph() {
void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
if (!recentlyAllocatedNodes)
return;
+
+ // Only periodically relcaim nodes so that we can build up a set of
+ // nodes that meet the reclamation criteria. Freshly created nodes
+ // by definition have no successor, and thus cannot be reclaimed (see below).
+ assert(reclaimCounter > 0);
+ if (--reclaimCounter != 0)
+ return;
+ reclaimCounter = CounterTop;
+
NodeList &nl = *getNodeList(recentlyAllocatedNodes);
// Reclaimn all nodes that match *all* the following criteria:
@@ -72,7 +89,7 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
// (5) The 'store' is the same as the predecessor.
// (6) The 'GDM' is the same as the predecessor.
// (7) The LocationContext is the same as the predecessor.
- // (8) The PostStmt is for a non-CFGElement expression.
+ // (8) The PostStmt is for a non-consumed Stmt or Expr.
for (NodeList::iterator i = nl.begin(), e = nl.end() ; i != e; ++i) {
ExplodedNode *node = *i;
@@ -110,8 +127,11 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
continue;
// Condition 8.
- if (node->getCFG().isBlkExpr(ps.getStmt()))
- continue;
+ if (const Expr *Ex = dyn_cast<Expr>(ps.getStmt())) {
+ ParentMap &PM = progPoint.getLocationContext()->getParentMap();
+ if (!PM.isConsumedExpr(Ex))
+ continue;
+ }
// If we reach here, we can remove the node. This means:
// (a) changing the predecessors successor to the successor of this node