diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-09-16 06:04:26 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-09-16 06:04:26 +0000 |
commit | 4f335c300a70da4a75c4e81e92f7ab3d12929500 (patch) | |
tree | 838b78c488184d9a31ebc3208eaa012f1b283934 | |
parent | f3f54ffc8910ba7f09b1f855babdf9db1965865b (diff) | |
download | bcm5719-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.cpp | 44 | ||||
-rw-r--r-- | clang/test/Analysis/uninit-vals-ps-region.c | 2 | ||||
-rw-r--r-- | clang/test/Analysis/uninit-vals-ps.c | 6 |
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; |