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.
//===----------------------------------------------------------------------===//
#ifndef NDEBUG
+static GRConstants* GraphPrintCheckerState;
+
namespace llvm {
template<>
struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
Out << "\\l";
}
+
+ if (GraphPrintCheckerState->isUninitControlFlow(N)) {
+ Out << "\\|Control-flow based on\\lUninitialized value.\\l";
+ }
}
}
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
else GeneratedFalse = true;
if (IsNew) {
- Eng.WList->Enqueue(GRWorkListUnit(Succ));
+ Deferred.push_back(Succ);
return Succ;
}
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));
}