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.

llvm-svn: 46582
This commit is contained in:
Ted Kremenek 2008-01-30 23:24:39 +00:00
parent a50d98565f
commit 2531fce319
3 changed files with 19 additions and 1 deletions

View File

@ -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

View File

@ -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));
}

View File

@ -167,6 +167,9 @@ class GRBranchNodeBuilderImpl {
CFGBlock* DstF;
ExplodedNodeImpl* Pred;
typedef llvm::SmallVector<ExplodedNodeImpl*,3> DeferredTy;
DeferredTy Deferred;
bool GeneratedTrue;
bool GeneratedFalse;