Added transfer function support for checking for divide-by-zero errors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47547 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 2931d2a..74fadcc 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -850,6 +850,33 @@
BinaryOperator::Opcode Op = B->getOpcode();
+ if (Op == BinaryOperator::Div) { // Check for divide-by-zero.
+
+ // First, "assume" that the denominator is 0.
+
+ bool isFeasible = false;
+ StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
+
+ if (isFeasible) {
+ NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
+
+ if (DivZeroNode) {
+ DivZeroNode->markAsSink();
+ DivZeroes.insert(DivZeroNode);
+ }
+ }
+
+ // Second, "assume" that the denominator cannot be 0.
+
+ isFeasible = false;
+ St = Assume(St, RightV, true, isFeasible);
+
+ if (!isFeasible)
+ continue;
+
+ // Fall-through. The logic below processes the divide.
+ }
+
if (Op <= BinaryOperator::Or) {
// Process non-assignements except commas or short-circuited
@@ -964,8 +991,35 @@
RightV = EvalCast(RightV, CTy);
// Evaluate operands and promote to result type.
+
+ if (Op == BinaryOperator::Div) { // Check for divide-by-zero.
+
+ // First, "assume" that the denominator is 0.
+
+ bool isFeasible = false;
+ StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
+
+ if (isFeasible) {
+ NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
+
+ if (DivZeroNode) {
+ DivZeroNode->markAsSink();
+ DivZeroes.insert(DivZeroNode);
+ }
+ }
+
+ // Second, "assume" that the denominator cannot be 0.
+
+ isFeasible = false;
+ St = Assume(St, RightV, true, isFeasible);
+
+ if (!isFeasible)
+ continue;
+
+ // Fall-through. The logic below processes the divide.
+ }
+
RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
-
St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);
}
}