]> granicus.if.org Git - clang/commitdiff
Unify the implementation of getLValueElement of store managers.
authorZhongxing Xu <xuzhongxing@gmail.com>
Mon, 8 Feb 2010 08:17:02 +0000 (08:17 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Mon, 8 Feb 2010 08:17:02 +0000 (08:17 +0000)
It's more sophisticated than the original one of BasicStore. But it does
matter.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95536 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Checker/PathSensitive/Store.h
lib/Checker/BasicStore.cpp
lib/Checker/FlatStore.cpp
lib/Checker/RegionStore.cpp
lib/Checker/Store.cpp

index 2ab09a197e37486d519c86200f6c7e0912eb2c1e..c660e7b7feeebb4f915fa5d303bc1efe2df6d35c 100644 (file)
@@ -110,7 +110,7 @@ public:
     return getLValueFieldOrIvar(D, Base);
   }
 
-  virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
+  virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
 
   // FIXME: Make out-of-line.
   virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, 
index de9643e91e3938a60b6aad597435181774265bab..294b9555a51da935d89225ec169c642f73086315 100644 (file)
@@ -70,8 +70,6 @@ public:
     return store;
   }
 
-  SVal getLValueElement(QualType elementType, SVal Offset, SVal Base);
-
   /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
   ///  conversions between arrays and pointers.
   SVal ArrayToPointer(Loc Array) { return Array; }
@@ -111,59 +109,6 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
   return new BasicStoreManager(StMgr);
 }
 
-SVal BasicStoreManager::getLValueElement(QualType elementType,
-                                         SVal Offset, SVal Base) {
-
-  if (Base.isUnknownOrUndef())
-    return Base;
-
-  Loc BaseL = cast<Loc>(Base);
-  const MemRegion* BaseR = 0;
-
-  switch(BaseL.getSubKind()) {
-    case loc::GotoLabelKind:
-      // Technically we can get here if people do funny things with casts.
-      return UndefinedVal();
-
-    case loc::MemRegionKind: {
-      const MemRegion *R = cast<loc::MemRegionVal>(BaseL).getRegion();
-
-      if (isa<ElementRegion>(R)) {
-        // int x;
-        // char* y = (char*) &x;
-        // 'y' => ElementRegion(0, VarRegion('x'))
-        // y[0] = 'a';
-        return Base;
-      }
-
-      if (isa<TypedRegion>(R) || isa<SymbolicRegion>(R)) {
-        BaseR = R;
-        break;
-      }
-
-      break;
-    }
-
-    case loc::ConcreteIntKind:
-      // While these seem funny, this can happen through casts.
-      // FIXME: What we should return is the field offset.  For example,
-      //  add the field offset to the integer value.  That way funny things
-      //  like this work properly:  &(((struct foo *) 0xa)->f)
-      return Base;
-
-    default:
-      assert ("Unhandled Base.");
-      return Base;
-  }
-
-  if (BaseR) {
-    return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(),
-                                                 BaseR, getContext()));
-  }
-  else
-    return UnknownVal();
-}
-
 static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
   bool foundPointer = false;
   while (1) {
index f427ae1cecc8aa4ecb267b4fc422f4be69ec05ba..fcb95f9385ccf7d2580e50bd0527b954d2b81c75 100644 (file)
@@ -42,7 +42,6 @@ public:
     return 0;
   }
 
-  SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
   SVal ArrayToPointer(Loc Array);
   Store RemoveDeadBindings(Store store, Stmt* Loc, SymbolReaper& SymReaper,
                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots){
@@ -126,11 +125,6 @@ Store FlatStoreManager::BindCompoundLiteral(Store store,
   return store;
 }
 
-SVal FlatStoreManager::getLValueElement(QualType elementType, SVal offset, 
-                                        SVal Base) {
-  return UnknownVal();
-}
-
 SVal FlatStoreManager::ArrayToPointer(Loc Array) {
   return Array;
 }
index 1917e53e82432559ee6cdf92bc6d6f65f28a5295..93905a29dacfb23cbaa4a2e137dac7d09cce2f96 100644 (file)
@@ -232,9 +232,6 @@ public:
   ///  the value is not specified.  
   Store setImplicitDefaultValue(Store store, const MemRegion *R, QualType T);
 
-  SVal getLValueElement(QualType elementType, SVal Offset, SVal Base);
-
-
   /// ArrayToPointer - Emulates the "decay" of an array to a pointer
   ///  type.  'Array' represents the lvalue of the array being decayed
   ///  to a pointer, and the returned SVal represents the decayed
@@ -652,60 +649,6 @@ Store RegionStoreManager::InvalidateRegions(Store store,
                              StateMgr.getValueManager());
 }
   
-SVal RegionStoreManager::getLValueElement(QualType elementType, SVal Offset, 
-                                          SVal Base) {
-
-  // If the base is an unknown or undefined value, just return it back.
-  // FIXME: For absolute pointer addresses, we just return that value back as
-  //  well, although in reality we should return the offset added to that
-  //  value.
-  if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
-    return Base;
-
-  // Only handle integer offsets... for now.
-  if (!isa<nonloc::ConcreteInt>(Offset))
-    return UnknownVal();
-
-  const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
-
-  // Pointer of any type can be cast and used as array base.
-  const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
-
-  // Convert the offset to the appropriate size and signedness.
-  Offset = ValMgr.convertToArrayIndex(Offset);
-
-  if (!ElemR) {
-    //
-    // If the base region is not an ElementRegion, create one.
-    // This can happen in the following example:
-    //
-    //   char *p = __builtin_alloc(10);
-    //   p[1] = 8;
-    //
-    //  Observe that 'p' binds to an AllocaRegion.
-    //
-    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
-                                                    BaseRegion, getContext()));
-  }
-
-  SVal BaseIdx = ElemR->getIndex();
-
-  if (!isa<nonloc::ConcreteInt>(BaseIdx))
-    return UnknownVal();
-
-  const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
-  const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
-  assert(BaseIdxI.isSigned());
-
-  // Compute the new index.
-  SVal NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI));
-
-  // Construct the new ElementRegion.
-  const MemRegion *ArrayR = ElemR->getSuperRegion();
-  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
-                                                  getContext()));
-}
-
 //===----------------------------------------------------------------------===//
 // Extents for regions.
 //===----------------------------------------------------------------------===//
index 7190bdabb6bb23f9bbc895f1207d11d70c4fa25c..d68369dfa5de7b27eae9798452cd52f8f3dd347b 100644 (file)
@@ -270,3 +270,58 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl* D, SVal Base) {
 
   return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
 }
+
+SVal StoreManager::getLValueElement(QualType elementType, SVal Offset, 
+                                    SVal Base) {
+
+  // If the base is an unknown or undefined value, just return it back.
+  // FIXME: For absolute pointer addresses, we just return that value back as
+  //  well, although in reality we should return the offset added to that
+  //  value.
+  if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
+    return Base;
+
+  // Only handle integer offsets... for now.
+  if (!isa<nonloc::ConcreteInt>(Offset))
+    return UnknownVal();
+
+  const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
+
+  // Pointer of any type can be cast and used as array base.
+  const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
+
+  // Convert the offset to the appropriate size and signedness.
+  Offset = ValMgr.convertToArrayIndex(Offset);
+
+  if (!ElemR) {
+    //
+    // If the base region is not an ElementRegion, create one.
+    // This can happen in the following example:
+    //
+    //   char *p = __builtin_alloc(10);
+    //   p[1] = 8;
+    //
+    //  Observe that 'p' binds to an AllocaRegion.
+    //
+    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
+                                                    BaseRegion, Ctx));
+  }
+
+  SVal BaseIdx = ElemR->getIndex();
+
+  if (!isa<nonloc::ConcreteInt>(BaseIdx))
+    return UnknownVal();
+
+  const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+  const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
+  assert(BaseIdxI.isSigned());
+
+  // Compute the new index.
+  SVal NewIdx = nonloc::ConcreteInt(
+                      ValMgr.getBasicValueFactory().getValue(BaseIdxI + OffI));
+
+  // Construct the new ElementRegion.
+  const MemRegion *ArrayR = ElemR->getSuperRegion();
+  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
+                                                  Ctx));
+}