]> granicus.if.org Git - clang/commitdiff
Added getLValueElement() to RegionStore. Only handle constant array for now.
authorZhongxing Xu <xuzhongxing@gmail.com>
Fri, 24 Oct 2008 01:09:32 +0000 (01:09 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Fri, 24 Oct 2008 01:09:32 +0000 (01:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58058 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/RegionStore.cpp

index 1bd29add306c5566865c21a67773879fd6e47a75..f64ed76be7221b4c486021ce911e5676fe9d025f 100644 (file)
@@ -44,6 +44,10 @@ public:
 
   SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D);
 
+  SVal getLValueElement(const GRState* St, SVal Base, SVal Offset);
+
+  SVal ArrayToPointer(SVal Array);
+
   SVal Retrieve(Store S, Loc L, QualType T);
 
   Store Bind(Store St, Loc LV, SVal V);
@@ -124,6 +128,56 @@ SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base,
   return loc::MemRegionVal(MRMgr.getFieldRegion(D, BaseR));
 }
 
+SVal RegionStoreManager::getLValueElement(const GRState* St, 
+                                          SVal Base, SVal Offset) {
+  if (Base.isUnknownOrUndef())
+    return Base;
+
+  loc::MemRegionVal& BaseL = cast<loc::MemRegionVal>(Base);
+
+  // We expect BaseR is an ElementRegion, not a base VarRegion.
+
+  const ElementRegion* ElemR = cast<ElementRegion>(BaseL.getRegion());
+
+  SVal Idx = ElemR->getIndex();
+
+  nonloc::ConcreteInt *CI1, *CI2;
+
+  // Only handle integer indices for now.
+  if ((CI1 = dyn_cast<nonloc::ConcreteInt>(&Idx)) &&
+      (CI2 = dyn_cast<nonloc::ConcreteInt>(&Offset))) {
+    SVal NewIdx = CI1->EvalBinOp(StateMgr.getBasicVals(), BinaryOperator::Add,
+                                 *CI2);
+    return loc::MemRegionVal(MRMgr.getElementRegion(NewIdx, 
+                                                    ElemR->getSuperRegion()));
+  }
+
+  return UnknownVal();
+}
+
+// Cast 'pointer to array' to 'pointer to the first element of array'.
+
+SVal RegionStoreManager::ArrayToPointer(SVal Array) {
+  const MemRegion* ArrayR = cast<loc::MemRegionVal>(&Array)->getRegion();
+
+  const VarDecl* D = cast<VarRegion>(ArrayR)->getDecl();
+
+  if (const ConstantArrayType* CAT = 
+      dyn_cast<ConstantArrayType>(D->getType().getTypePtr())) {
+
+    BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+    
+    nonloc::ConcreteInt Idx(BasicVals.getValue(0, CAT->getSize().getBitWidth(),
+                                               false));
+
+    ElementRegion* ER = MRMgr.getElementRegion(Idx, ArrayR);
+    
+    return loc::MemRegionVal(ER);
+  }
+
+  return Array;
+}
+
 SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) {
   assert(!isa<UnknownVal>(L) && "location unknown");
   assert(!isa<UndefinedVal>(L) && "location undefined");