[analyzer] Make sure that inlined defensive checks work on div by zero.

This suppresses a false positive in std::hash_map.
Fixes  radar://14255587.

llvm-svn: 185608
This commit is contained in:
Anna Zaks 2013-07-04 02:38:06 +00:00
parent 6597b8fd22
commit 5673b6567a
3 changed files with 46 additions and 5 deletions

View File

@ -532,7 +532,8 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
// If we have an expression that provided the value, try to track where it
// came from.
if (InitE) {
if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
if (V.isUndef() ||
V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
if (!IsParam)
InitE = InitE->IgnoreParenCasts();
bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam,
@ -996,12 +997,15 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
BugReporterVisitor *ConstraintTracker =
new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
report.addVisitor(ConstraintTracker);
}
// Add visitor, which will suppress inline defensive checks.
if (LVState->isNull(V).isConstrainedTrue() &&
EnableNullFPSuppression) {
// Add visitor, which will suppress inline defensive checks.
if (Optional<DefinedSVal> DV = V.getAs<DefinedSVal>()) {
if (!DV->isZeroConstant() &&
LVState->isNull(*DV).isConstrainedTrue() &&
EnableNullFPSuppression) {
BugReporterVisitor *IDCSuppressor =
new SuppressInlineDefensiveChecksVisitor(V.castAs<DefinedSVal>(),
new SuppressInlineDefensiveChecksVisitor(*DV,
LVNode);
report.addVisitor(IDCSuppressor);
}

View File

@ -84,6 +84,14 @@ void testMultipleStore(void *p) {
#endif
}
// Test that div by zero does not get suppressed. This is a policy choice.
int retZero() {
return 0;
}
int triggerDivZero () {
int y = retZero();
return 5/y; // expected-warning {{Division by zero}}
}
// --------------------------
// "Suppression suppression"

View File

@ -110,3 +110,32 @@ void testConstantOffset(char *value) {
cursor++;
}
}
// Ensure idc works for integer zero values (ex: suppressed div by zero).
void idcZero(int assume) {
if (assume)
;
}
int idcTriggerZeroValue(int m) {
idcZero(m);
return 5/m; // no-warning
}
int idcTriggerZeroValueThroughCall(int i) {
return 5/i; // no-warning
}
void idcTrackZeroValueThroughCall(int x) {
idcZero(x);
idcTriggerZeroValueThroughCall(x);
}
int idcTriggerZeroThroughDoubleAssignemnt(int i) {
return 5/i; // no-warning
}
void idcTrackZeroThroughDoubleAssignemnt(int x) {
idcZero(x);
int y = x;
int z = y;
idcTriggerZeroValueThroughCall(z);
}