]> granicus.if.org Git - clang/commitdiff
Add a GDM for recording the cast type of regions.
authorZhongxing Xu <xuzhongxing@gmail.com>
Wed, 6 May 2009 08:33:50 +0000 (08:33 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Wed, 6 May 2009 08:33:50 +0000 (08:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71076 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/RegionStore.cpp

index 5f8e6c3f92a715aee88fa31d729b95ff8ea30e53..043fc95e084829d4a3aaa22330cea05747b3e2eb 100644 (file)
@@ -48,6 +48,17 @@ namespace clang {
   };
 }
 
+// RegionCasts records the current cast type of a region.
+namespace { class VISIBILITY_HIDDEN RegionCasts {}; }
+static int RegionCastsIndex = 0;
+namespace clang {
+  template<> struct GRStateTrait<RegionCasts>
+    : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, 
+                                                    QualType> > {
+    static void* GDMIndex() { return &RegionCastsIndex; }
+  };
+}
+
 //===----------------------------------------------------------------------===//
 // Region "Extents"
 //===----------------------------------------------------------------------===//
@@ -253,6 +264,7 @@ public:
   }
 
   const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent);
+  const GRState* setCastType(const GRState* St, const MemRegion* R, QualType T);
 
   static inline RegionBindingsTy GetRegionBindings(Store store) {
    return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
@@ -488,6 +500,9 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
       // return the size as signed integer.
       return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false);
     }
+
+    // If the VarRegion is cast to other type, compute the size with respect to
+    // that type.
     
     // Clients can use ordinary variables as if they were arrays.  These
     // essentially are arrays of size 1.
@@ -650,9 +665,11 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
       || isa<ObjCIvarRegion>(R) || isa<CompoundLiteralRegion>(R)) {
     if (isSmallerThan(PointeeTy, 
                       cast<TypedRegion>(R)->getRValueType(getContext()))) {
+      // Record the cast type of the region.
+      state = setCastType(state, R, ToTy);
+
       SVal Idx = ValMgr.makeZeroArrayIndex();
-      ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx, 
-                                                 cast<TypedRegion>(R));
+      ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx, R);
       return CastResult(state, ER);
     } else
       return CastResult(state, R);
@@ -1295,3 +1312,9 @@ const GRState* RegionStoreManager::RemoveRegionView(const GRState* St,
 
   return state.set<RegionViewMap>(Base, V);
 }
+
+const GRState* RegionStoreManager::setCastType(const GRState* St,
+                                               const MemRegion* R, QualType T) {
+  GRStateRef state(St, StateMgr);
+  return state.set<RegionCasts>(R, T);
+}