aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-11-27 23:05:37 +0000
committerTed Kremenek <kremenek@apple.com>2012-11-27 23:05:37 +0000
commitbd8a11e224c3ec6cbc4bb9b1fc70a8aa3a633e43 (patch)
tree3484cd2b37b3b5ca9436253cf3f352a6f62325dc
parent82c458ea76bf8f0981e3d1b5070c0b0e5878d784 (diff)
Provide stop-gap solution to crash reported in PR 14436.
This was also covered by <rdar://problem/12753384>. The static analyzer evaluates a CXXConstructExpr within an initializer expression and RegionStore doesn't know how to handle the resulting CXXTempObjectRegion that gets created. We need a better solution than just dropping the value, but we need to better understand how to implement the right semantics here. Thanks to Jordan for his help diagnosing the behavior here. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168741 91177308-0d34-0410-b5e6-96231b3b80d8
-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;
+}
+