Implemented more boilerplate in GREngine for processing branches. Now
we automatically generate a new successor node along an edge if the checker
did not explicitly do so (i.e., we just propagate the current state).
llvm-svn: 46536
diff --git a/clang/Analysis/GRConstants.cpp b/clang/Analysis/GRConstants.cpp
index 2c6c7f7..ad00b60 100644
--- a/clang/Analysis/GRConstants.cpp
+++ b/clang/Analysis/GRConstants.cpp
@@ -831,8 +831,7 @@
/// ProcessBranch - Called by GREngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
- void ProcessBranch(Stmt* Condition, Stmt* Term, BranchNodeBuilder& builder)
- {}
+ void ProcessBranch(Stmt* Condition, Stmt* Term, BranchNodeBuilder& builder);
/// RemoveDeadBindings - Return a new state that is the same as 'M' except
/// that all subexpression mappings are removed and that any
@@ -877,6 +876,12 @@
} // end anonymous namespace
+void GRConstants::ProcessBranch(Stmt* Condition, Stmt* Term,
+ BranchNodeBuilder& builder) {
+
+
+}
+
void GRConstants::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
Builder = &builder;
diff --git a/clang/Analysis/GREngine.cpp b/clang/Analysis/GREngine.cpp
index 35101a9..43ee864 100644
--- a/clang/Analysis/GREngine.cpp
+++ b/clang/Analysis/GREngine.cpp
@@ -296,6 +296,14 @@
Succ->addPredecessor(Pred);
+ if (branch) GeneratedTrue = true;
+ else GeneratedFalse = true;
+
if (IsNew)
Eng.WList->Enqueue(GRWorkListUnit(Succ));
}
+
+GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
+ if (!GeneratedTrue) generateNodeImpl(Pred->State, true);
+ if (!GeneratedFalse) generateNodeImpl(Pred->State, false);
+}
diff --git a/clang/include/clang/Analysis/PathSensitive/GREngine.h b/clang/include/clang/Analysis/PathSensitive/GREngine.h
index c3a9e20..175b1fb 100644
--- a/clang/include/clang/Analysis/PathSensitive/GREngine.h
+++ b/clang/include/clang/Analysis/PathSensitive/GREngine.h
@@ -167,12 +167,16 @@
CFGBlock* DstF;
ExplodedNodeImpl* Pred;
+ bool GeneratedTrue;
+ bool GeneratedFalse;
+
public:
GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
ExplodedNodeImpl* pred, GREngineImpl* e)
- : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred) {}
+ : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
+ GeneratedTrue(false), GeneratedFalse(false) {}
- ~GRBranchNodeBuilderImpl() {}
+ ~GRBranchNodeBuilderImpl();
const ExplodedGraphImpl& getGraph() const { return *Eng.G; }