aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp5
-rw-r--r--test/Analysis/misc-ps-region-store.cpp19
2 files changed, 24 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index fe17773fc7..d0d8f601f0 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1063,6 +1063,11 @@ SVal RegionStoreManager::RetrieveElement(Store store,
// return *y;
// FIXME: This is a hack, and doesn't do anything really intelligent yet.
const RegionRawOffset &O = R->getAsArrayOffset();
+
+ // If we cannot reason about the offset, return an unknown value.
+ if (!O.getRegion())
+ return UnknownVal();
+
if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) {
QualType baseT = baseR->getValueType();
if (baseT->isScalarType()) {
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index b122bffaae..7959359596 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -395,3 +395,22 @@ unsigned test_invalidate_in_ctor_new() {
return x; // no-warning
}
+// Test assigning into a symbolic offset.
+struct TestAssignIntoSymbolicOffset {
+ int **stuff[100];
+ void test(int x, int y);
+};
+
+void TestAssignIntoSymbolicOffset::test(int x, int y) {
+ x--;
+ if (x > 8 || x < 0)
+ return;
+ if (stuff[x])
+ return;
+ if (!stuff[x]) {
+ stuff[x] = new int*[y+1];
+ // Previously triggered a null dereference.
+ stuff[x][y] = 0; // no-warning
+ }
+}
+