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 3cd490e..33f7f51 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -75,6 +75,21 @@
// 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 @@
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 @@
const NonLValue& R2 = cast<NonLValue>(V2);
Result = EvalBinaryOp(ValMgr, Op, L1, R2);
}
- else if (isa<LValue>(V2)) { // LValue comparison.
+ else if (isa<LValue>(V2)) {
const LValue& L2 = cast<LValue>(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<NonLValue>(GetValue(N1->getState(), L1)),
+ cast<NonLValue>(GetValue(N2->getState(), L2)));
+ }
}
- else { // Any operation between two Non-LValues.
+ else { // Any other operation between two Non-LValues.
const NonLValue& R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
const NonLValue& R2 = cast<NonLValue>(V2);
Result = EvalBinaryOp(ValMgr, Op, R1, R2);