Skip to content

Commit dea8c07

Browse files
committed
Don't emit divide-by-zero errors when we divide by an unknown (not
uninitialized) value. At this point we're just too imprecise. llvm-svn: 47636
1 parent 3bfca3e commit dea8c07

File tree

1 file changed

+57
-45
lines changed

1 file changed

+57
-45
lines changed

clang/Analysis/GRExprEngine.cpp

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -952,41 +952,44 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
952952

953953
// Check if the denominator is uninitialized.
954954

955-
if (RightV.isUninit()) {
956-
NodeTy* DivUninit = Builder->generateNode(B, St, N2);
955+
if (!RightV.isUnknown()) {
956+
957+
if (RightV.isUninit()) {
958+
NodeTy* DivUninit = Builder->generateNode(B, St, N2);
959+
960+
if (DivUninit) {
961+
DivUninit->markAsSink();
962+
BadDivides.insert(DivUninit);
963+
}
964+
965+
continue;
966+
}
967+
968+
// Check for divide/remainder-by-zero.
969+
//
970+
// First, "assume" that the denominator is 0 or uninitialized.
971+
972+
bool isFeasible = false;
973+
StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
957974

958-
if (DivUninit) {
959-
DivUninit->markAsSink();
960-
BadDivides.insert(DivUninit);
975+
if (isFeasible) {
976+
NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
977+
978+
if (DivZeroNode) {
979+
DivZeroNode->markAsSink();
980+
BadDivides.insert(DivZeroNode);
981+
}
961982
}
962983

963-
continue;
964-
}
984+
// Second, "assume" that the denominator cannot be 0.
965985

966-
// Check for divide/remainder-by-zero.
967-
//
968-
// First, "assume" that the denominator is 0 or uninitialized.
969-
970-
bool isFeasible = false;
971-
StateTy ZeroSt = Assume(St, RightV, false,isFeasible);
972-
973-
if (isFeasible) {
974-
NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
986+
isFeasible = false;
987+
St = Assume(St, RightV, true, isFeasible);
975988

976-
if (DivZeroNode) {
977-
DivZeroNode->markAsSink();
978-
BadDivides.insert(DivZeroNode);
979-
}
989+
if (!isFeasible)
990+
continue;
980991
}
981992

982-
// Second, "assume" that the denominator cannot be 0.
983-
984-
isFeasible = false;
985-
St = Assume(St, RightV, true, isFeasible);
986-
987-
if (!isFeasible)
988-
continue;
989-
990993
// Fall-through. The logic below processes the divide.
991994
}
992995

@@ -1032,7 +1035,14 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
10321035

10331036
default: {
10341037

1035-
assert (B->isCompoundAssignmentOp());
1038+
assert (B->isCompoundAssignmentOp());
1039+
1040+
if (Op >= BinaryOperator::AndAssign)
1041+
((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
1042+
else
1043+
((int&) Op) -= BinaryOperator::MulAssign;
1044+
1045+
// Check if the LHS is uninitialized.
10361046

10371047
if (LeftV.isUninit()) {
10381048
HandleUninitializedStore(B, N2);
@@ -1058,18 +1068,13 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
10581068

10591069
LVal LeftLV = cast<LVal>(LeftV);
10601070

1061-
// Propagate uninitialized values (right-side).
1062-
1063-
if (RightV.isUninit()) {
1064-
St = SetRVal(SetRVal(St, B, RightV), LeftLV, RightV);
1065-
break;
1066-
}
1067-
10681071
// Fetch the value of the LHS (the value of the variable, etc.).
10691072

10701073
RVal V = GetRVal(N1->getState(), LeftLV, B->getLHS()->getType());
10711074

1072-
// Propagate uninitialized value (left-side).
1075+
// Propagate uninitialized value (left-side). We
1076+
// propogate uninitialized values for the RHS below when
1077+
// we also check for divide-by-zero.
10731078

10741079
if (V.isUninit()) {
10751080
St = SetRVal(St, B, V);
@@ -1088,13 +1093,10 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
10881093
break;
10891094
}
10901095

1091-
// Neither the LHS or the RHS have Unknown/Uninit values. Process
1092-
// the operation and store the result.
1093-
1094-
if (Op >= BinaryOperator::AndAssign)
1095-
((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
1096-
else
1097-
((int&) Op) -= BinaryOperator::MulAssign;
1096+
// At this point:
1097+
//
1098+
// The LHS is not Uninit/Unknown.
1099+
// The RHS is not Unknown.
10981100

10991101
// Get the computation type.
11001102
QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
@@ -1120,7 +1122,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
11201122

11211123
continue;
11221124
}
1123-
1125+
11241126
// First, "assume" that the denominator is 0.
11251127

11261128
bool isFeasible = false;
@@ -1145,6 +1147,16 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
11451147

11461148
// Fall-through. The logic below processes the divide.
11471149
}
1150+
else {
1151+
1152+
// Propagate uninitialized values (right-side).
1153+
1154+
if (RightV.isUninit()) {
1155+
St = SetRVal(SetRVal(St, B, RightV), LeftLV, RightV);
1156+
break;
1157+
}
1158+
1159+
}
11481160

11491161
RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
11501162
St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);

0 commit comments

Comments
 (0)