forked from OSchip/llvm-project
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:
parent
a50d98565f
commit
2531fce319
|
@ -842,6 +842,10 @@ public:
|
||||||
|
|
||||||
return St;
|
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
|
/// ProcessStmt - Called by GREngine. Used to generate new successor
|
||||||
/// nodes by processing the 'effects' of a block-level statement.
|
/// 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
|
#ifndef NDEBUG
|
||||||
|
static GRConstants* GraphPrintCheckerState;
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template<>
|
template<>
|
||||||
struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
|
struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
|
||||||
|
@ -1566,6 +1572,10 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
|
||||||
|
|
||||||
Out << "\\l";
|
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);
|
GREngine<GRConstants> Engine(cfg, FD, Ctx);
|
||||||
Engine.ExecuteWorkList();
|
Engine.ExecuteWorkList();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
GraphPrintCheckerState = &Engine.getCheckerState();
|
||||||
llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
|
llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
|
||||||
|
GraphPrintCheckerState = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} // end clang namespace
|
} // end clang namespace
|
||||||
|
|
|
@ -301,7 +301,7 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
|
||||||
else GeneratedFalse = true;
|
else GeneratedFalse = true;
|
||||||
|
|
||||||
if (IsNew) {
|
if (IsNew) {
|
||||||
Eng.WList->Enqueue(GRWorkListUnit(Succ));
|
Deferred.push_back(Succ);
|
||||||
return Succ;
|
return Succ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,4 +311,7 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
|
||||||
GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
|
GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
|
||||||
if (!GeneratedTrue) generateNodeImpl(Pred->State, true);
|
if (!GeneratedTrue) generateNodeImpl(Pred->State, true);
|
||||||
if (!GeneratedFalse) generateNodeImpl(Pred->State, false);
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,9 @@ class GRBranchNodeBuilderImpl {
|
||||||
CFGBlock* DstF;
|
CFGBlock* DstF;
|
||||||
ExplodedNodeImpl* Pred;
|
ExplodedNodeImpl* Pred;
|
||||||
|
|
||||||
|
typedef llvm::SmallVector<ExplodedNodeImpl*,3> DeferredTy;
|
||||||
|
DeferredTy Deferred;
|
||||||
|
|
||||||
bool GeneratedTrue;
|
bool GeneratedTrue;
|
||||||
bool GeneratedFalse;
|
bool GeneratedFalse;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue