aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-01-30 23:24:39 +0000
committerTed Kremenek <kremenek@apple.com>2008-01-30 23:24:39 +0000
commit3b4f6702860208692f6ef28401e68de4e3ff9af9 (patch)
tree985e57508d9acfeb9f0079b5dd890dc9fca9ce31
parentb38911f16b4943548db6a3695fc6ae23070b25d2 (diff)
We now delay adding nodes created by GRBranchNodeBuilder to the analysis
worklist until the dstor of GRBranchNodeBuilderImpl. This way clients can mark creates nodes as "sinks" before they are added to the worklist. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46582 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Analysis/GRConstants.cpp12
-rw-r--r--Analysis/GREngine.cpp5
-rw-r--r--include/clang/Analysis/PathSensitive/GREngine.h3
3 files changed, 19 insertions, 1 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index 6d5bdbd119..36ad5fe20a 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -842,6 +842,10 @@ public:
return St;
}
+
+ bool isUninitControlFlow(const NodeTy* N) const {
+ return N->isSink() && UninitBranches.count(const_cast<NodeTy*>(N)) != 0;
+ }
/// ProcessStmt - Called by GREngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
@@ -1474,6 +1478,8 @@ StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption,
//===----------------------------------------------------------------------===//
#ifndef NDEBUG
+static GRConstants* GraphPrintCheckerState;
+
namespace llvm {
template<>
struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
@@ -1566,6 +1572,10 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
Out << "\\l";
}
+
+ if (GraphPrintCheckerState->isUninitControlFlow(N)) {
+ Out << "\\|Control-flow based on\\lUninitialized value.\\l";
+ }
}
}
@@ -1587,7 +1597,9 @@ void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx) {
GREngine<GRConstants> Engine(cfg, FD, Ctx);
Engine.ExecuteWorkList();
#ifndef NDEBUG
+ GraphPrintCheckerState = &Engine.getCheckerState();
llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
+ GraphPrintCheckerState = NULL;
#endif
}
} // end clang namespace
diff --git a/Analysis/GREngine.cpp b/Analysis/GREngine.cpp
index 46fbd187f1..8e86d08daa 100644
--- a/Analysis/GREngine.cpp
+++ b/Analysis/GREngine.cpp
@@ -301,7 +301,7 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
else GeneratedFalse = true;
if (IsNew) {
- Eng.WList->Enqueue(GRWorkListUnit(Succ));
+ Deferred.push_back(Succ);
return Succ;
}
@@ -311,4 +311,7 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
if (!GeneratedTrue) generateNodeImpl(Pred->State, true);
if (!GeneratedFalse) generateNodeImpl(Pred->State, false);
+
+ for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
+ if (!(*I)->isSink()) Eng.WList->Enqueue(GRWorkListUnit(*I));
}
diff --git a/include/clang/Analysis/PathSensitive/GREngine.h b/include/clang/Analysis/PathSensitive/GREngine.h
index 8c3fc12bb9..cb3366e3c0 100644
--- a/include/clang/Analysis/PathSensitive/GREngine.h
+++ b/include/clang/Analysis/PathSensitive/GREngine.h
@@ -167,6 +167,9 @@ class GRBranchNodeBuilderImpl {
CFGBlock* DstF;
ExplodedNodeImpl* Pred;
+ typedef llvm::SmallVector<ExplodedNodeImpl*,3> DeferredTy;
+ DeferredTy Deferred;
+
bool GeneratedTrue;
bool GeneratedFalse;