summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/Analysis/GRConstants.cpp12
-rw-r--r--clang/Analysis/GREngine.cpp5
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GREngine.h3
3 files changed, 19 insertions, 1 deletions
diff --git a/clang/Analysis/GRConstants.cpp b/clang/Analysis/GRConstants.cpp
index 6d5bdbd1199..36ad5fe20a8 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<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/clang/Analysis/GREngine.cpp b/clang/Analysis/GREngine.cpp
index 46fbd187f17..8e86d08daad 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 8c3fc12bb91..cb3366e3c06 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<ExplodedNodeImpl*,3> DeferredTy;
+ DeferredTy Deferred;
+
bool GeneratedTrue;
bool GeneratedFalse;
OpenPOWER on IntegriCloud