From: Ted Kremenek Date: Fri, 15 Feb 2008 22:29:00 +0000 (+0000) Subject: Added transfer function support for conditional branches with a NULL condition (e... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2331834a0515c80862ee51325c758a053829f15;p=clang Added transfer function support for conditional branches with a NULL condition (e.g., "for(;;)"). Fixed bug in transfer function for compound assignment operators when both operands where variables but had a non-pointer type (we fired an assertion). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47184 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index 3cd490e330..33f7f51504 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -75,6 +75,21 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, // Remove old bindings for subexpressions. StateTy PrevState = StateMgr.RemoveSubExprBindings(builder.getState()); + // Check for NULL conditions; e.g. "for(;;)" + if (!Condition) { + builder.markInfeasible(false); + + // Get the current block counter. + GRBlockCounter BC = builder.getBlockCounter(); + unsigned BlockID = builder.getTargetBlock(true)->getBlockID(); + unsigned NumVisited = BC.getNumVisited(BlockID); + + if (NumVisited < 1) builder.generateNode(PrevState, true); + else builder.markInfeasible(true); + + return; + } + RValue V = GetValue(PrevState, Condition); switch (V.getBaseKind()) { @@ -98,10 +113,9 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, return; } } - + // Get the current block counter. GRBlockCounter BC = builder.getBlockCounter(); - unsigned BlockID = builder.getTargetBlock(true)->getBlockID(); unsigned NumVisited = BC.getNumVisited(BlockID); @@ -708,11 +722,22 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, const NonLValue& R2 = cast(V2); Result = EvalBinaryOp(ValMgr, Op, L1, R2); } - else if (isa(V2)) { // LValue comparison. + else if (isa(V2)) { const LValue& L2 = cast(V2); - Result = EvalBinaryOp(ValMgr, Op, L1, L2); + + if (B->getRHS()->getType()->isPointerType()) { + // LValue comparison. + Result = EvalBinaryOp(ValMgr, Op, L1, L2); + } + else { + // An operation between two variables of a non-lvalue type. + Result = + EvalBinaryOp(ValMgr, Op, + cast(GetValue(N1->getState(), L1)), + cast(GetValue(N2->getState(), L2))); + } } - else { // Any operation between two Non-LValues. + else { // Any other operation between two Non-LValues. const NonLValue& R1 = cast(GetValue(N1->getState(), L1)); const NonLValue& R2 = cast(V2); Result = EvalBinaryOp(ValMgr, Op, R1, R2);