]> granicus.if.org Git - clang/commitdiff
[analyzer] Make sure that inlined defensive checks work on div by zero.
authorAnna Zaks <ganna@apple.com>
Thu, 4 Jul 2013 02:38:06 +0000 (02:38 +0000)
committerAnna Zaks <ganna@apple.com>
Thu, 4 Jul 2013 02:38:06 +0000 (02:38 +0000)
This suppresses a false positive in std::hash_map.
Fixes  radar://14255587.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185608 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
test/Analysis/inlining/false-positive-suppression.c
test/Analysis/inlining/inline-defensive-checks.c

index fe579a3fbf32430f63f10945591bfb6eadc902c0..ffc8f09dcb86ed7e92e6fdb85f4436ae4810e04f 100644 (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);
         }
index c5c6bb875ea238e6cafa7d01bc132a163ce92857..e1c8f67614e11b37e071298d549101c22e726996 100644 (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"
index aa7f70030c064ff6df1d549188aa24cefcc402e8..4ce783c852fe5e6444f2fba1ee066227cc50041f 100644 (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);
+}