]> granicus.if.org Git - clang/commitdiff
Fix RegionStore bug when doing a field load whose parent is also a field assigned...
authorTed Kremenek <kremenek@apple.com>
Sun, 3 Apr 2011 04:09:15 +0000 (04:09 +0000)
committerTed Kremenek <kremenek@apple.com>
Sun, 3 Apr 2011 04:09:15 +0000 (04:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128783 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 03615950259d549ef52f85197f7c749728bb9f36..f14b8ad94ff6fabe4579fef4abf5d3b3e0f703ea 100644 (file)
@@ -358,7 +358,8 @@ public: // Part of public interface to class.
 
   /// Get the state and region whose binding this region R corresponds to.
   std::pair<Store, const MemRegion*>
-  GetLazyBinding(RegionBindings B, const MemRegion *R);
+  GetLazyBinding(RegionBindings B, const MemRegion *R,
+                 const MemRegion *originalRegion);
 
   StoreRef CopyLazyBindings(nonloc::LazyCompoundVal V, Store store,
                             const TypedRegion *R);
@@ -979,10 +980,20 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
 }
 
 std::pair<Store, const MemRegion *>
-RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
+RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R,
+                                   const MemRegion *originalRegion) {
+  
+  if (originalRegion != R) {
+    if (Optional<SVal> OV = getDefaultBinding(B, R)) {
+      if (const nonloc::LazyCompoundVal *V =
+          dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer()))
+        return std::make_pair(V->getStore(), V->getRegion());
+    }
+  }
+  
   if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
     const std::pair<Store, const MemRegion *> &X =
-      GetLazyBinding(B, ER->getSuperRegion());
+      GetLazyBinding(B, ER->getSuperRegion(), originalRegion);
 
     if (X.second)
       return std::make_pair(X.first,
@@ -990,7 +1001,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
   }
   else if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
     const std::pair<Store, const MemRegion *> &X =
-      GetLazyBinding(B, FR->getSuperRegion());
+      GetLazyBinding(B, FR->getSuperRegion(), originalRegion);
 
     if (X.second)
       return std::make_pair(X.first,
@@ -1001,17 +1012,12 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
   else if (const CXXBaseObjectRegion *baseReg = 
                             dyn_cast<CXXBaseObjectRegion>(R)) {
     const std::pair<Store, const MemRegion *> &X =
-      GetLazyBinding(B, baseReg->getSuperRegion());
+      GetLazyBinding(B, baseReg->getSuperRegion(), originalRegion);
     
     if (X.second)
       return std::make_pair(X.first,
                      MRMgr.getCXXBaseObjectRegionWithSuper(baseReg, X.second));
   }
-  else if (Optional<SVal> OV = getDefaultBinding(B, R)) {
-    if (const nonloc::LazyCompoundVal *V =
-        dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer()))
-      return std::make_pair(V->getStore(), V->getRegion());
-  }
 
   // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is
   // possible for a valid lazy binding.
@@ -1158,7 +1164,7 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
   // Lazy binding?
   Store lazyBindingStore = NULL;
   const MemRegion *lazyBindingRegion = NULL;
-  llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R);
+  llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R);
 
   if (lazyBindingRegion)
     return RetrieveLazyBinding(lazyBindingRegion, lazyBindingStore);
index 46446af0bc5f12211e1df6050d1c2a79df3da0f2..be0356d176b5fef6dec009a288b980dc9a2a13f1 100644 (file)
@@ -1274,3 +1274,28 @@ int PR9455_2() {
   return 1;
 }
 
+// Test initialization of substructs via lazy compound values.
+typedef float RDar9163742_Float;
+
+typedef struct {
+    RDar9163742_Float x, y;
+} RDar9163742_Point;
+typedef struct {
+    RDar9163742_Float width, height;
+} RDar9163742_Size;
+typedef struct {
+    RDar9163742_Point origin;
+    RDar9163742_Size size;
+} RDar9163742_Rect;
+
+extern  RDar9163742_Rect RDar9163742_RectIntegral(RDar9163742_Rect);
+
+RDar9163742_Rect RDar9163742_IntegralRect(RDar9163742_Rect frame)
+{
+    RDar9163742_Rect integralFrame;
+    integralFrame.origin.x = frame.origin.x;
+    integralFrame.origin.y = frame.origin.y;
+    integralFrame.size = frame.size;
+    return RDar9163742_RectIntegral(integralFrame); // no-warning; all fields initialized
+}
+