[cfe-commits] r127796 - in /cfe/trunk: lib/StaticAnalyzer/Core/RegionStore.cpp test/Analysis/misc-ps-region-store.m

Ted Kremenek kremenek at apple.com
Wed Mar 16 20:51:51 PDT 2011


Author: kremenek
Date: Wed Mar 16 22:51:51 2011
New Revision: 127796

URL: http://llvm.org/viewvc/llvm-project?rev=127796&view=rev
Log:
Tweak RegionStore's handling of lazy compound values to use the 'Default' versus 'Direct' binding key, thus allowing specific elements of an array/struct to be overwritten without
invalidating the entire binding.  Fixes PR 9455.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/test/Analysis/misc-ps-region-store.m

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=127796&r1=127795&r2=127796&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Wed Mar 16 22:51:51 2011
@@ -337,6 +337,9 @@
 
   SVal RetrieveFieldOrElementCommon(Store store, const TypedRegion *R,
                                     QualType Ty, const MemRegion *superR);
+  
+  SVal RetrieveLazyBinding(const MemRegion *lazyBindingRegion,
+                           Store lazyBindingStore);
 
   /// Retrieve the values in a struct and return a CompoundVal, used when doing
   /// struct copy:
@@ -977,11 +980,6 @@
 
 std::pair<Store, const MemRegion *>
 RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
-  if (Optional<SVal> OV = getDirectBinding(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());
@@ -1009,6 +1007,12 @@
       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.
   return std::make_pair((Store) 0, (const MemRegion *) 0);
@@ -1098,14 +1102,19 @@
                                                 QualType Ty) {
 
   if (const Optional<SVal> &D = getDefaultBinding(B, superR)) {
-    if (SymbolRef parentSym = D->getAsSymbol())
+    const SVal &val = D.getValue();
+    if (SymbolRef parentSym = val.getAsSymbol())
       return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
 
-    if (D->isZeroConstant())
+    if (val.isZeroConstant())
       return svalBuilder.makeZeroVal(Ty);
 
-    if (D->isUnknownOrUndef())
-      return *D;
+    if (val.isUnknownOrUndef())
+      return val;
+
+    // Lazy bindings are handled later.
+    if (isa<nonloc::LazyCompoundVal>(val))
+      return Optional<SVal>();
 
     assert(0 && "Unknown default value");
   }
@@ -1113,6 +1122,15 @@
   return Optional<SVal>();
 }
 
+SVal RegionStoreManager::RetrieveLazyBinding(const MemRegion *lazyBindingRegion,
+                                             Store lazyBindingStore) {
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))
+    return RetrieveElement(lazyBindingStore, ER);
+  
+  return RetrieveField(lazyBindingStore,
+                       cast<FieldRegion>(lazyBindingRegion));
+}
+                                        
 SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
                                                       const TypedRegion *R,
                                                       QualType Ty,
@@ -1142,12 +1160,8 @@
   const MemRegion *lazyBindingRegion = NULL;
   llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R);
 
-  if (lazyBindingRegion) {
-    if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))
-      return RetrieveElement(lazyBindingStore, ER);
-    return RetrieveField(lazyBindingStore,
-                         cast<FieldRegion>(lazyBindingRegion));
-  }
+  if (lazyBindingRegion)
+    return RetrieveLazyBinding(lazyBindingRegion, lazyBindingStore);
 
   if (R->hasStackNonParametersStorage()) {
     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
@@ -1530,7 +1544,7 @@
 
   // Now copy the bindings.  This amounts to just binding 'V' to 'R'.  This
   // results in a zero-copy algorithm.
-  return StoreRef(addBinding(B, R, BindingKey::Direct,
+  return StoreRef(addBinding(B, R, BindingKey::Default,
                              V).getRootWithoutRetain(), *this);
 }
 

Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=127796&r1=127795&r2=127796&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.m Wed Mar 16 22:51:51 2011
@@ -1253,4 +1253,24 @@
   }
 }
 
+// Test handling binding lazy compound values to a region and then have
+// specific elements have other bindings.
+int PR9455() {
+  char arr[4] = "000";
+  arr[0] = '1';
+  if (arr[1] == '0')
+    return 1;
+  int *p = 0;
+  *p = 0xDEADBEEF; // no-warning
+  return 1;
+}
+int PR9455_2() {
+  char arr[4] = "000";
+  arr[0] = '1';
+  if (arr[1] == '0') {
+    int *p = 0;
+    *p = 0xDEADBEEF; // expected-warning {{null}}
+  }
+  return 1;
+}
 





More information about the cfe-commits mailing list