]> granicus.if.org Git - clang/commitdiff
Provide stop-gap solution to crash reported in PR 14436.
authorTed Kremenek <kremenek@apple.com>
Tue, 27 Nov 2012 23:05:37 +0000 (23:05 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 27 Nov 2012 23:05:37 +0000 (23:05 +0000)
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

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

index aed994df4110e442c2bf02827c7410f6266f7b0b..875a7ce4d4e42215e23dd8eb7713de428a7ed64a 100644 (file)
@@ -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.
index adbc5b1df0d3fdd97e6f3ad6fffc53cbf53e3b4f..6d43509cdd0523ed4b09fb96366b8b2c7f92e528 100644 (file)
@@ -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;
+}
+