aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp18
-rw-r--r--test/Analysis/misc-ps-region-store.cpp23
2 files changed, 33 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index aed994df41..875a7ce4d4 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1581,14 +1581,16 @@ StoreRef RegionStoreManager::BindArray(Store store, const TypedValueRegion* R,
Size = CAT->getSize().getZExtValue();
// Check if the init expr is a string literal.
- if (loc::MemRegionVal *MRV = dyn_cast<loc::MemRegionVal>(&Init)) {
- const StringRegion *S = cast<StringRegion>(MRV->getRegion());
-
- // Treat the string as a lazy compound value.
- nonloc::LazyCompoundVal LCV =
- cast<nonloc::LazyCompoundVal>(svalBuilder.
- makeLazyCompoundVal(StoreRef(store, *this), S));
- return BindAggregate(store, R, LCV);
+ if (const MemRegion *Reg = Init.getAsRegion()) {
+ if (const StringRegion *S = dyn_cast<StringRegion>(Reg)) {
+ // Treat the string as a lazy compound value.
+ NonLoc V = svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), S);
+ return BindAggregate(store, R, V);
+ }
+ // FIXME: Handle CXXTempObjectRegion, which can occur in cases
+ // where a struct contains an array of structs in C++.
+ assert(isa<CXXTempObjectRegion>(Reg));
+ return BindAggregate(store, R, UnknownVal());
}
// Handle lazy compound values.
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index adbc5b1df0..6d43509cdd 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -633,3 +633,26 @@ void test_alloca_in_a_recursive_function(int p1) {
test_alloca_in_a_recursive_function(1);
test_alloca_in_a_recursive_function(2);
}
+
+//===---------------------------------------------------------------------===//
+// Random tests.
+//===---------------------------------------------------------------------===//
+
+// Tests assigning using a C-style initializer to a struct
+// variable whose sub-field is also a struct. This currently
+// results in a CXXTempObjectRegion being created, but not
+// properly handled. For now, we just ignore that value
+// to avoid a crash (<rdar://problem/12753384>).
+struct RDar12753384_ClassA {
+ unsigned z;
+};
+struct RDar12753384_ClassB {
+ unsigned x;
+ RDar12753384_ClassA y[ 8 ] ;
+};
+unsigned RDar12753384() {
+ RDar12753384_ClassB w = { 0x00 };
+ RDar12753384_ClassA y[8];
+ return w.x;
+}
+