From 2531fce319dd676c29da3877048038137995cef4 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 30 Jan 2008 23:24:39 +0000 Subject: [PATCH] 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 --- clang/Analysis/GRConstants.cpp | 12 ++++++++++++ clang/Analysis/GREngine.cpp | 5 ++++- .../include/clang/Analysis/PathSensitive/GREngine.h | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang/Analysis/GRConstants.cpp b/clang/Analysis/GRConstants.cpp index 6d5bdbd1199d..36ad5fe20a80 100644 --- a/clang/Analysis/GRConstants.cpp +++ b/clang/Analysis/GRConstants.cpp @@ -842,6 +842,10 @@ public: return St; } + + bool isUninitControlFlow(const NodeTy* N) const { + return N->isSink() && UninitBranches.count(const_cast(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 : @@ -1566,6 +1572,10 @@ struct VISIBILITY_HIDDEN DOTGraphTraits : 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 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/clang/Analysis/GREngine.cpp b/clang/Analysis/GREngine.cpp index 46fbd187f178..8e86d08daade 100644 --- a/clang/Analysis/GREngine.cpp +++ b/clang/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/clang/include/clang/Analysis/PathSensitive/GREngine.h b/clang/include/clang/Analysis/PathSensitive/GREngine.h index 8c3fc12bb91a..cb3366e3c063 100644 --- a/clang/include/clang/Analysis/PathSensitive/GREngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GREngine.h @@ -167,6 +167,9 @@ class GRBranchNodeBuilderImpl { CFGBlock* DstF; ExplodedNodeImpl* Pred; + typedef llvm::SmallVector DeferredTy; + DeferredTy Deferred; + bool GeneratedTrue; bool GeneratedFalse;