]> granicus.if.org Git - clang/commitdiff
Implement BindStruct and fix a bug in RetriveStruct.
authorZhongxing Xu <xuzhongxing@gmail.com>
Fri, 31 Oct 2008 08:10:01 +0000 (08:10 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Fri, 31 Oct 2008 08:10:01 +0000 (08:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58496 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/RegionStore.cpp

index c2a5da728926f3cfceb77b433f034d9b07c1234b..224d65fa926207a62b79ac90493d66e4d3b30566 100644 (file)
@@ -115,7 +115,7 @@ private:
   Store InitializeStructToUndefined(Store store, QualType T, MemRegion* BaseR);
 
   SVal RetrieveStruct(Store store, const TypedRegion* R);
-
+  Store BindStruct(Store store, const TypedRegion* R, SVal V);
   // Utility methods.
   BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
   ASTContext& getContext() { return StateMgr.getContext(); }
@@ -267,7 +267,7 @@ SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
   for (int i = RD->getNumMembers() - 1; i >= 0; --i) {
     FieldRegion* FR = MRMgr.getFieldRegion(RD->getMember(i), R);
     RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(store));
-    RegionBindingsTy::data_type* data = B.lookup(R);
+    RegionBindingsTy::data_type* data = B.lookup(FR);
 
     SVal FieldValue = data ? *data : UnknownVal();
 
@@ -285,8 +285,11 @@ Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
 
   const MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
   
-  if (!R)
-    return store;
+  assert(R);
+
+  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
+    if (TR->getType(getContext())->isStructureType())
+      return BindStruct(store, TR, V);
 
   RegionBindingsTy B = GetRegionBindings(store);
   return V.isUnknown()
@@ -294,6 +297,32 @@ Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
          : RBFactory.Add(B, R, V).getRoot();
 }
 
+Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, SVal V){
+  QualType T = R->getType(getContext());
+  assert(T->isStructureType());
+
+  const RecordType* RT = cast<RecordType>(T.getTypePtr());
+  RecordDecl* RD = RT->getDecl();
+  assert(RD->isDefinition());
+
+  RegionBindingsTy B = GetRegionBindings(store);
+
+  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
+
+  nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
+  RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
+
+  for (; FI != FE; ++FI, ++VI) {
+    assert(VI != VE);
+
+    FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
+
+    B = RBFactory.Add(B, FR, *VI);
+  }
+
+  return B.getRoot();
+}
+
 Store RegionStoreManager::getInitialStore() {
   typedef LiveVariables::AnalysisDataTy LVDataTy;
   LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();