]> granicus.if.org Git - clang/commitdiff
region store: make Retrieve() can retrieve embedded array correctly. Also
authorZhongxing Xu <xuzhongxing@gmail.com>
Sun, 3 May 2009 00:27:40 +0000 (00:27 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sun, 3 May 2009 00:27:40 +0000 (00:27 +0000)
simplify the retrieve logic.

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

lib/Analysis/RegionStore.cpp
test/Analysis/array-struct.c

index aeb8a2ac8f86a9fb04052732fd1294bc9da04e32..8f573c39884d43083cbb9c52dc760e763384a7a1 100644 (file)
@@ -270,6 +270,8 @@ private:
   /// y's value is retrieved by this method.
   SVal RetrieveStruct(const GRState* St, const TypedRegion* R);
 
+  SVal RetrieveArray(const GRState* St, const TypedRegion* R);
+
   const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V);
 
   /// KillStruct - Set the entire struct to unknown. 
@@ -652,8 +654,13 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
   // Such funny addressing will occur due to layering of regions.
 
   QualType RTy = R->getRValueType(getContext());
+
   if (RTy->isStructureType())
     return RetrieveStruct(St, R);
+
+  if (RTy->isArrayType())
+    return RetrieveArray(St, R);
+
   // FIXME: handle Vector types.
   if (RTy->isVectorType())
       return UnknownVal();
@@ -732,10 +739,6 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
 }
 
 SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){
-
-  Store store = St->getStore();
-  GRStateRef state(St, StateMgr);
-
   // FIXME: Verify we want getRValueType instead of getLValueType.
   QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
@@ -753,27 +756,35 @@ SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){
                                                FieldEnd = Fields.rend();
        Field != FieldEnd; ++Field) {
     FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
-    RegionBindingsTy B = GetRegionBindings(store);
-    RegionBindingsTy::data_type* data = B.lookup(FR);
-
-    SVal FieldValue;
-    if (data)
-      FieldValue = *data;
-    else if (state.contains<RegionKills>(FR))
-      FieldValue = UnknownVal();
-    else {
-      if (MRMgr.onStack(FR) || MRMgr.onHeap(FR))
-        FieldValue = UndefinedVal();
-      else
-        FieldValue = ValMgr.getRValueSymbolVal(FR);
-    }
-
+    QualType FTy = (*Field)->getType();
+    SVal FieldValue = Retrieve(St, loc::MemRegionVal(FR), FTy);
     StructVal = getBasicVals().consVals(FieldValue, StructVal);
   }
 
   return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals());
 }
 
+SVal RegionStoreManager::RetrieveArray(const GRState* St, const TypedRegion* R){
+  QualType T = R->getRValueType(getContext());
+  ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
+
+  llvm::ImmutableList<SVal> ArrayVal = getBasicVals().getEmptySValList();
+
+  llvm::APSInt Size(CAT->getSize(), false);
+  llvm::APSInt i = getBasicVals().getValue(0, Size.getBitWidth(), 
+                                          Size.isUnsigned());
+
+  for (; i < Size; ++i) {
+    SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
+    ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
+    QualType ETy = ER->getRValueType(getContext());
+    SVal ElementVal = Retrieve(St, loc::MemRegionVal(ER), ETy);
+    ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal);
+  }
+
+  return NonLoc::MakeCompoundVal(T, ArrayVal, getBasicVals());
+}
+
 const GRState* RegionStoreManager::Bind(const GRState* St, Loc L, SVal V) {
   // If we get here, the location should be a region.
   const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
index 7e5e6243c6a8a94093a844b3068006c9f47f44ef..0ce6afcc0c0ab154a94575a884b05544fae76948 100644 (file)
@@ -119,3 +119,14 @@ void f13(double timeout) {
   if (a.e.d == 10)
     a.e.d = 4;
 }
+
+struct s3 {
+  int a[2];
+};
+
+static struct s3 opt;
+
+// Test if the embedded array is retrieved correctly.
+void f14() {
+  struct s3 my_opt = opt;
+}