[cfe-commits] r78349 - in /cfe/trunk: lib/Analysis/RegionStore.cpp test/Analysis/unions-region.m

Ted Kremenek kremenek at apple.com
Thu Aug 6 15:33:36 PDT 2009


Author: kremenek
Date: Thu Aug  6 17:33:36 2009
New Revision: 78349

URL: http://llvm.org/viewvc/llvm-project?rev=78349&view=rev
Log:
Fix a few more false positives involving RegionStore and unions, but this time
with array accesses. In the process, refactor some common logic in
RetrieveElement() and RetrieveField() into RetrieveFieldOrElementCommon().

Modified:
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/test/Analysis/unions-region.m

Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=78349&r1=78348&r2=78349&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Thu Aug  6 17:33:36 2009
@@ -315,6 +315,9 @@
   
   SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
   
+  SVal RetrieveFieldOrElementCommon(const GRState *state, const TypedRegion *R,
+                                    QualType Ty, const MemRegion *superR);
+  
   SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
                                          const TypedRegion *R, QualType castTy);
 
@@ -1053,109 +1056,66 @@
     }
   }
 
-  // Check if the super region has a default value.
-  if (const SVal *D = state->get<RegionDefaultValue>(superR)) {
-    if (D->hasConjuredSymbol())
-      return ValMgr.getRegionValueSymbolVal(R);
-    else
-      return *D;
-  }
-
-  // Check if the super region has a binding.
+  // Check if the immediate super region has a direct binding.
   if (const SVal *V = B.lookup(superR)) {
     if (SymbolRef parentSym = V->getAsSymbol())
       return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
 
     if (V->isUnknownOrUndef())
       return *V;
-    
-    // Handle LazyCompoundVals below.
-    if (const nonloc::LazyCompoundVal *LVC =
-          dyn_cast<nonloc::LazyCompoundVal>(V)) {
-      return RetrieveElement(LVC->getState(),
-                             MRMgr.getElementRegionWithSuper(R,
-                                                             LVC->getRegion()));
-    }
+
+    // Handle LazyCompoundVals for the immediate super region.  Other cases
+    // are handled in 'RetrieveFieldOrElementCommon'.
+    if (const nonloc::LazyCompoundVal *LCV = 
+        dyn_cast<nonloc::LazyCompoundVal>(V)) {
       
+      R = MRMgr.getElementRegionWithSuper(R, LCV->getRegion());
+      return RetrieveElement(LCV->getState(), R);
+    }
+    
     // Other cases: give up.
     return UnknownVal();
   }
   
-  // Lazy binding?
-  const GRState *lazyBindingState = NULL;
-  const MemRegion *LazyBindingRegion = NULL;
-  llvm::tie(lazyBindingState, LazyBindingRegion) = GetLazyBinding(B, R);
-  
-  if (lazyBindingState) {
-    assert(LazyBindingRegion && "Lazy-binding region not set");
-    return RetrieveElement(lazyBindingState,
-                           cast<ElementRegion>(LazyBindingRegion));
-  }
-
-  // Default value cases.
-#if 0
-  if (R->hasHeapStorage()) {
-      // FIXME: If the region has heap storage and we know nothing special
-      // about its bindings, should we instead return UnknownVal?  Seems like
-      // we should only return UndefinedVal in the cases where we know the value
-      // will be undefined.
-    return UndefinedVal();
-  }
-#endif
-  
-  if (R->hasStackStorage() && !R->hasParametersStorage()) {
-    // Currently we don't reason specially about Clang-style vectors.  Check
-    // if superR is a vector and if so return Unknown.
-    if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
-      if (typedSuperR->getValueType(getContext())->isVectorType())
-        return UnknownVal();
-    }
-
-    return UndefinedVal();
-  }
-
-  QualType Ty = R->getValueType(getContext());
-
-  return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
+  return RetrieveFieldOrElementCommon(state, R, R->getElementType(), superR);
 }
 
 SVal RegionStoreManager::RetrieveField(const GRState* state, 
                                        const FieldRegion* R) {
-  QualType Ty = R->getValueType(getContext());
 
   // Check if the region has a binding.
   RegionBindings B = GetRegionBindings(state->getStore());
   if (const SVal* V = B.lookup(R))
     return *V;
 
-  const MemRegion* superR = R->getSuperRegion();
+  QualType Ty = R->getValueType(getContext());
+  return RetrieveFieldOrElementCommon(state, R, Ty, R->getSuperRegion());
+}
+  
+SVal RegionStoreManager::RetrieveFieldOrElementCommon(const GRState *state,
+                                                      const TypedRegion *R,
+                                                      QualType Ty,
+                                                      const MemRegion *superR) {
+
+  // At this point we have already checked in either RetrieveElement or 
+  // RetrieveField if 'R' has a direct binding.
+  
+  RegionBindings B = GetRegionBindings(state->getStore());
+    
   while (superR) {
     if (const Optional<SVal> &D = getDefaultBinding(state, superR)) {
       if (SymbolRef parentSym = D->getAsSymbol())
         return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
-
+      
       if (D->isZeroConstant())
         return ValMgr.makeZeroVal(Ty);
-      
-      if (const nonloc::LazyCompoundVal *LCV =
-            dyn_cast<nonloc::LazyCompoundVal>(D)) {
-        const FieldRegion *FR =
-          MRMgr.getFieldRegionWithSuper(R, LCV->getRegion());
-        return RetrieveField(LCV->getState(), FR);
-      }
-
+            
       if (D->isUnknown())
         return *D;
-
+      
       assert(0 && "Unknown default value");
     }
     
-    if (const SVal *V = B.lookup(superR)) {
-      // Handle LazyCompoundVals below.
-      if (isa<nonloc::CompoundVal>(*V))
-        break;
-    }
-   
     // If our super region is a field or element itself, walk up the region
     // hierarchy to see if there is a default value installed in an ancestor.
     if (isa<FieldRegion>(superR) || isa<ElementRegion>(superR)) {
@@ -1168,28 +1128,38 @@
   
   // Lazy binding?
   const GRState *lazyBindingState = NULL;
-  const MemRegion *LazyBindingRegion = NULL;
-  llvm::tie(lazyBindingState, LazyBindingRegion) = GetLazyBinding(B, R);
+  const MemRegion *lazyBindingRegion = NULL;
+  llvm::tie(lazyBindingState, lazyBindingRegion) = GetLazyBinding(B, R);
   
   if (lazyBindingState) {
-    assert(LazyBindingRegion && "Lazy-binding region not set");
+    assert(lazyBindingRegion && "Lazy-binding region not set");
+    
+    if (isa<ElementRegion>(R))
+      return RetrieveElement(lazyBindingState,
+                             cast<ElementRegion>(lazyBindingRegion));
+    
     return RetrieveField(lazyBindingState,
-                        cast<FieldRegion>(LazyBindingRegion));
-  }
-
-#if HEAP_UNDEFINED
-  // FIXME: Is this correct?  Should it be UnknownVal?
-  if (R->hasHeapStorage())
-    return UndefinedVal();
-#endif
+                         cast<FieldRegion>(lazyBindingRegion));
+  } 
   
-  if (R->hasStackStorage() && !R->hasParametersStorage())
+  if (R->hasStackStorage() && !R->hasParametersStorage()) {
+    
+    if (isa<ElementRegion>(R)) {
+      // Currently we don't reason specially about Clang-style vectors.  Check
+      // if superR is a vector and if so return Unknown.
+      if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
+        if (typedSuperR->getValueType(getContext())->isVectorType())
+          return UnknownVal();
+      }      
+    }
+    
     return UndefinedVal();
-
+  }
+  
   // All other values are symbolic.
   return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
 }
-
+  
 SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state, 
                                           const ObjCIvarRegion* R) {
 

Modified: cfe/trunk/test/Analysis/unions-region.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unions-region.m?rev=78349&r1=78348&r2=78349&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/unions-region.m (original)
+++ cfe/trunk/test/Analysis/unions-region.m Thu Aug  6 17:33:36 2009
@@ -6,10 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// When using RegionStore, this test case previously had a false positive
-// of a 'pass-by-value argument is uninitialized' warning at the call to
-// 'testA_aux'.
-
+// [testA] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testA_aux' and 'testA_aux_2'.
 union u_testA {
   unsigned i;
   float f;
@@ -30,3 +29,13 @@
   return swap.f;  
 }
 
+// [testB] When using RegionStore, this test case previously had a
+// false positive of a 'pass-by-value argument is uninitialized'
+// warning at the call to 'testB_aux'.
+void testB(int i) {
+  void testB_aux(short z);
+  union { short x[2]; unsigned y; } val;  
+  val.y = 10;
+  testB_aux(val.x[1]); // no-warning
+}
+





More information about the cfe-commits mailing list