From: Ted Kremenek Date: Mon, 20 Jul 2009 18:44:36 +0000 (+0000) Subject: Enhance GRBranchNodeBuilderImpl (part of GRCoreEngine) to understand the case X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=520035439d7133064325c4df6378c5a8f2f05539;p=clang Enhance GRBranchNodeBuilderImpl (part of GRCoreEngine) to understand the case where the true or false CFGBlock* for a branch could be NULL. This will handle the case where we can determine during CFG construction that a branch is infeasible. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76450 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index 0fbdbde55b..0285ad6989 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -311,12 +311,15 @@ class GRBranchNodeBuilderImpl { bool GeneratedTrue; bool GeneratedFalse; + bool InFeasibleTrue; + bool InFeasibleFalse; public: GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF, ExplodedNodeImpl* pred, GRCoreEngineImpl* e) : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred), - GeneratedTrue(false), GeneratedFalse(false) {} + GeneratedTrue(false), GeneratedFalse(false), + InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} ~GRBranchNodeBuilderImpl(); @@ -331,8 +334,14 @@ public: } void markInfeasible(bool branch) { - if (branch) GeneratedTrue = true; - else GeneratedFalse = true; + if (branch) + InFeasibleTrue = GeneratedTrue = true; + else + InFeasibleFalse = GeneratedFalse = true; + } + + bool isFeasible(bool branch) { + return branch ? !InFeasibleTrue : !InFeasibleFalse; } }; @@ -374,6 +383,10 @@ public: void markInfeasible(bool branch) { NB.markInfeasible(branch); } + + bool isFeasible(bool branch) { + return NB.isFeasible(branch); + } }; class GRIndirectGotoNodeBuilderImpl { diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp index d55bf6d9f8..5641baac5f 100644 --- a/lib/Analysis/GRCoreEngine.cpp +++ b/lib/Analysis/GRCoreEngine.cpp @@ -452,7 +452,12 @@ GRStmtNodeBuilderImpl::generateNodeImpl(PostStmt Loc, const void* State, } ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State, - bool branch) { + bool branch) { + + // If the branch has been marked infeasible we should not generate a node. + if (!isFeasible(branch)) + return NULL; + bool IsNew; ExplodedNodeImpl* Succ = @@ -460,8 +465,10 @@ ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State, Succ->addPredecessor(Pred); - if (branch) GeneratedTrue = true; - else GeneratedFalse = true; + if (branch) + GeneratedTrue = true; + else + GeneratedFalse = true; if (IsNew) { Deferred.push_back(Succ); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 8a1bd1831f..97e75fa0ac 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -706,16 +706,20 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term, } // Process the true branch. - if (const GRState *state = PrevState->assume(V, true)) - builder.generateNode(MarkBranch(state, Term, true), true); - else - builder.markInfeasible(true); + if (builder.isFeasible(true)) { + if (const GRState *state = PrevState->assume(V, true)) + builder.generateNode(MarkBranch(state, Term, true), true); + else + builder.markInfeasible(true); + } // Process the false branch. - if (const GRState *state = PrevState->assume(V, false)) - builder.generateNode(MarkBranch(state, Term, false), false); - else - builder.markInfeasible(false); + if (builder.isFeasible(false)) { + if (const GRState *state = PrevState->assume(V, false)) + builder.generateNode(MarkBranch(state, Term, false), false); + else + builder.markInfeasible(false); + } } /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor