[analyzer] Fix a bug in region store that lead to undefined value false
authorAnna Zaks <ganna@apple.com>
Thu, 31 Jan 2013 01:19:52 +0000 (01:19 +0000)
committerAnna Zaks <ganna@apple.com>
Thu, 31 Jan 2013 01:19:52 +0000 (01:19 +0000)
positives.

The includeSuffix was only set on the first iteration through the
function, resulting in invalid regions being produced by getLazyBinding
(ex: zoomRegion.y).

llvm-svn: 174016

clang/lib/StaticAnalyzer/Core/RegionStore.cpp
clang/test/Analysis/array-struct-region.c

index bbc34f2..a37223a 100644 (file)
@@ -489,8 +489,7 @@ 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(RegionBindingsConstRef B, const MemRegion *R,
-                 const MemRegion *originalRegion,
-                 bool includeSuffix = false);
+                 const MemRegion *originalRegion);
 
   //===------------------------------------------------------------------===//
   // State pruning.
@@ -1220,9 +1219,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
 std::pair<Store, const MemRegion *>
 RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
                                    const MemRegion *R,
-                                   const MemRegion *originalRegion,
-                                   bool includeSuffix) {
-  
+                                   const MemRegion *originalRegion) {
   if (originalRegion != R) {
     if (Optional<SVal> OV = B.getDefaultBinding(R)) {
       if (const nonloc::LazyCompoundVal *V =
@@ -1244,10 +1241,8 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
       getLazyBinding(B, FR->getSuperRegion(), originalRegion);
 
     if (X.second) {
-      if (includeSuffix)
-        return std::make_pair(X.first,
-                              MRMgr.getFieldRegionWithSuper(FR, X.second));
-      return X;
+      return std::make_pair(X.first,
+                            MRMgr.getFieldRegionWithSuper(FR, X.second));
     }
         
   }
@@ -1259,11 +1254,9 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
       getLazyBinding(B, baseReg->getSuperRegion(), originalRegion);
     
     if (X.second) {
-      if (includeSuffix)
-        return std::make_pair(X.first,
-                              MRMgr.getCXXBaseObjectRegionWithSuper(baseReg,
-                                                                    X.second));
-      return X;
+      return std::make_pair(X.first,
+                            MRMgr.getCXXBaseObjectRegionWithSuper(baseReg,
+                                                                  X.second));
     }
   }
 
@@ -1408,8 +1401,7 @@ RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
   // Lazy binding?
   Store lazyBindingStore = NULL;
   const MemRegion *lazyBindingRegion = NULL;
-  llvm::tie(lazyBindingStore, lazyBindingRegion) = getLazyBinding(B, R, R,
-                                                                  true);
+  llvm::tie(lazyBindingStore, lazyBindingRegion) = getLazyBinding(B, R, R);
   if (lazyBindingRegion)
     return getLazyBinding(lazyBindingRegion,
                           getRegionBindings(lazyBindingStore));
index d628c47..c4d9aff 100644 (file)
@@ -253,6 +253,19 @@ int testStructFieldChainsNested(int index, int anotherIndex) {
   return 0;
 }
 
+typedef struct {
+  int zoomLevel;
+  struct point center;
+} Outer;
+
+extern int test13116945(struct point x);
+static void radar13116945(struct point centerCoordinate) {
+  Outer zoomRegion;
+  zoomRegion.zoomLevel = 0;
+  zoomRegion.center = centerCoordinate;
+  Outer r = zoomRegion;
+  test13116945(r.center); // no-warning
+}
 
 // --------------------
 // False positives
@@ -289,4 +302,3 @@ void testFieldChainIsNotEnough(int index) {
   // FIXME: Should be TRUE.
   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{UNKNOWN}}
 }
-