summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-09-16 06:04:26 +0000
committerTed Kremenek <kremenek@apple.com>2009-09-16 06:04:26 +0000
commit4f335c300a70da4a75c4e81e92f7ab3d12929500 (patch)
tree838b78c488184d9a31ebc3208eaa012f1b283934
parentf3f54ffc8910ba7f09b1f855babdf9db1965865b (diff)
downloadbcm5719-llvm-4f335c300a70da4a75c4e81e92f7ab3d12929500.tar.gz
bcm5719-llvm-4f335c300a70da4a75c4e81e92f7ab3d12929500.zip
Have divide-by-zero checker not handled undefined denominators. This is handled by the generic checking for undefined operands for BinaryOperators.
llvm-svn: 82019
-rw-r--r--clang/lib/Analysis/GRExprEngineInternalChecks.cpp44
-rw-r--r--clang/test/Analysis/uninit-vals-ps-region.c2
-rw-r--r--clang/test/Analysis/uninit-vals-ps.c6
3 files changed, 22 insertions, 30 deletions
diff --git a/clang/lib/Analysis/GRExprEngineInternalChecks.cpp b/clang/lib/Analysis/GRExprEngineInternalChecks.cpp
index 21f14652047..2eb5589117f 100644
--- a/clang/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ b/clang/lib/Analysis/GRExprEngineInternalChecks.cpp
@@ -194,8 +194,7 @@ public:
class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
public:
DivZero(GRExprEngine* eng = 0)
- : BuiltinBug(eng,"Division-by-zero",
- "Division by zero or undefined value.") {}
+ : BuiltinBug(eng,"Division by zero") {}
void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode* N,
@@ -222,24 +221,26 @@ public:
llvm::SmallString<256> sbuf;
llvm::raw_svector_ostream OS(sbuf);
const GRState *ST = N->getState();
- const Expr *Ex = NULL;
+ const Expr *Ex = NULL;
+ bool isLeft = true;
if (ST->getSVal(B->getLHS()).isUndef()) {
Ex = B->getLHS()->IgnoreParenCasts();
- OS << "The left operand of the '";
+ isLeft = true;
}
else if (ST->getSVal(B->getRHS()).isUndef()) {
Ex = B->getRHS()->IgnoreParenCasts();
- OS << "The right operand of the '";
+ isLeft = false;
}
-
- if (Ex) {
- OS << BinaryOperator::getOpcodeStr(B->getOpcode())
- << "' expression is an undefined "
- "or otherwise garbage value";
+
+ if (Ex) {
+ OS << "The " << (isLeft ? "left" : "right")
+ << " operand of the '"
+ << BinaryOperator::getOpcodeStr(B->getOpcode())
+ << "' expression is a garbage value";
}
else {
- // We KNOW that the result was undefined.
+ // Neither operand was undefined, but the result is undefined.
OS << "The result of the '"
<< BinaryOperator::getOpcodeStr(B->getOpcode())
<< "' expression is undefined";
@@ -268,8 +269,10 @@ public:
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S)) {
const GRState *ST = N->getState();
- X = ST->getSVal(B->getLHS()).isUndef()
- ? B->getLHS()->IgnoreParenCasts() : B->getRHS()->IgnoreParenCasts();
+ if (ST->getSVal(B->getLHS()).isUndef())
+ X = B->getLHS();
+ else if (ST->getSVal(B->getRHS()).isUndef())
+ X = B->getRHS();
}
registerTrackNullOrUndefValue(BRC, X, N);
@@ -766,22 +769,11 @@ void CheckBadDiv::PreVisitBinaryOperator(CheckerContext &C,
!B->getRHS()->getType()->isScalarType())
return;
- // Check for divide by undefined.
SVal Denom = C.getState()->getSVal(B->getRHS());
-
- if (Denom.isUndef()) {
- if (ExplodedNode *N = C.GenerateNode(B, true)) {
- if (!BT)
- BT = new DivZero();
-
- C.EmitReport(new BuiltinBugReport(*BT, BT->getDescription().c_str(), N));
- }
- return;
- }
-
- // Handle the case where 'Denom' is UnknownVal.
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
+ // Divide-by-undefined handled in the generic checking for uses of
+ // undefined values.
if (!DV)
return;
diff --git a/clang/test/Analysis/uninit-vals-ps-region.c b/clang/test/Analysis/uninit-vals-ps-region.c
index d16200743c4..716b7c920fa 100644
--- a/clang/test/Analysis/uninit-vals-ps-region.c
+++ b/clang/test/Analysis/uninit-vals-ps-region.c
@@ -25,7 +25,7 @@ void test_uninit_pos() {
struct TestUninit v2 = test_uninit_aux();
int z;
v1.y = z;
- test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand of the '+' expression is an undefined or otherwise garbage value}}
+ test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand of the '+' expression is a garbage value}}
}
void test_uninit_neg() {
struct TestUninit v1 = { 0, 0 };
diff --git a/clang/test/Analysis/uninit-vals-ps.c b/clang/test/Analysis/uninit-vals-ps.c
index ac0e7b2f327..32b4324a7da 100644
--- a/clang/test/Analysis/uninit-vals-ps.c
+++ b/clang/test/Analysis/uninit-vals-ps.c
@@ -22,7 +22,7 @@ int f2() {
int x;
- if (x+1) // expected-warning{{The left operand of the '+' expression is an undefined or otherwise garbage value}}
+ if (x+1) // expected-warning{{The left operand of the '+' expression is a garbage value}}
return 1;
return 2;
@@ -31,13 +31,13 @@ int f2() {
int f2_b() {
int x;
- return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of the '+' expression is an undefined or otherwise garbage value}}
+ return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of the '+' expression is a garbage value}}
}
int f3(void) {
int i;
int *p = &i;
- if (*p > 0) // expected-warning{{The left operand of the '>' expression is an undefined or otherwise garbage value}}
+ if (*p > 0) // expected-warning{{The left operand of the '>' expression is a garbage value}}
return 0;
else
return 1;
OpenPOWER on IntegriCloud