Correctly handle IntegralToBool casts in C++ in the static analyzer. Fixes <rdar...
authorTed Kremenek <kremenek@apple.com>
Thu, 29 Nov 2012 00:50:20 +0000 (00:50 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 29 Nov 2012 00:50:20 +0000 (00:50 +0000)
llvm-svn: 168843

clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
clang/test/Analysis/misc-ps-region-store.cpp

index fbc6ba0..12da82e 100644 (file)
@@ -101,6 +101,12 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
   if (!isa<nonloc::ConcreteInt>(val))
     return UnknownVal();
 
+  // Handle casts to a boolean type.
+  if (castTy->isBooleanType()) {
+    bool b = cast<nonloc::ConcreteInt>(val).getValue().getBoolValue();
+    return makeTruthVal(b, castTy);
+  }
+
   // Only handle casts from integers to integers - if val is an integer constant
   // being cast to a non integer type, produce unknown.
   if (!isLocType && !castTy->isIntegerType())
@@ -735,7 +741,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
         NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
         if (!LeftIndex)
           return UnknownVal();
-        LeftIndexVal = evalCastFromNonLoc(*LeftIndex, resultTy);
+        LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
         LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
         if (!LeftIndex)
           return UnknownVal();
@@ -745,7 +751,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
         NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
         if (!RightIndex)
           return UnknownVal();
-        RightIndexVal = evalCastFromNonLoc(*RightIndex, resultTy);
+        RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
         RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
         if (!RightIndex)
           return UnknownVal();
index 1252140..7b7b8bd 100644 (file)
@@ -694,3 +694,14 @@ const Rdar12755044_foo *radar12755044() {
   static const Rdar12755044_foo Rdar12755044_foo_list[] = { { { } } };
   return Rdar12755044_foo_list; // no-warning
 }
+
+// Test the correct handling of integer to bool conversions.  Previously
+// this resulted in a false positive because integers were being truncated
+// and not tested for non-zero.
+void rdar12759044() {
+  int flag = 512;
+  if (!(flag & 512)) {
+   int *p = 0;
+   *p = 0xDEADBEEF; // no-warning
+  }
+}