aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp10
-rw-r--r--test/Analysis/misc-ps-region-store.cpp11
2 files changed, 19 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index fbc6ba0551..12da82e3f0 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -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();
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 1252140110..7b7b8bd300 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -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
+ }
+}