]> granicus.if.org Git - clang/commitdiff
Make StoreManager::InvalidateRegion() virtual, move the current implementation
authorTed Kremenek <kremenek@apple.com>
Wed, 29 Jul 2009 18:16:25 +0000 (18:16 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 29 Jul 2009 18:16:25 +0000 (18:16 +0000)
in StoreManager to RegionStoreManager, and create a special, highly reduced
version in BasicStoreManager.

These changes are in preparation for future RegionStore-specific changes to
InvalidateRegion.

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

include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/BasicStore.cpp
lib/Analysis/RegionStore.cpp
lib/Analysis/Store.cpp

index 37fc641c2e1e2e4d5b903fcd5e0c765019fea728..c0409d06a125a908d0fae927156c120448b5aef1 100644 (file)
@@ -170,8 +170,10 @@ public:
   virtual const GRState *BindDeclWithNoInit(const GRState *state,
                                              const VarDecl *vd) = 0;
 
-  const GRState *InvalidateRegion(const GRState *state, const MemRegion *R,
-                                  const Expr *E, unsigned Count);
+  virtual const GRState *InvalidateRegion(const GRState *state,
+                                          const MemRegion *R,
+                                          const Expr *E, unsigned Count) = 0;
+
   // FIXME: Make out-of-line.
   virtual const GRState *setExtent(const GRState *state,
                                     const MemRegion *region, SVal extent) {
index f276975e9bd9a287b69c97c680f568f4d746ce11..b84bdf41005fa52e6f1f1d184b8600c56f3a3024 100644 (file)
@@ -50,7 +50,10 @@ public:
   }
 
   SValuator::CastResult Retrieve(const GRState *state, Loc loc,
-                                 QualType T = QualType());  
+                                 QualType T = QualType());
+  
+  const GRState *InvalidateRegion(const GRState *state, const MemRegion *R,
+                                  const Expr *E, unsigned Count);
 
   const GRState *Bind(const GRState *state, Loc L, SVal V) {
     return state->makeWithStore(BindInternal(state->getStore(), L, V));
@@ -623,3 +626,27 @@ void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
 }
 
 StoreManager::BindingsHandler::~BindingsHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Binding invalidation.
+//===----------------------------------------------------------------------===//
+
+const GRState *BasicStoreManager::InvalidateRegion(const GRState *state,
+                                                   const MemRegion *R,
+                                                   const Expr *E,
+                                                   unsigned Count) {
+  R = R->getBaseRegion();
+  
+  if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+      return state;
+      
+  // We only track bindings to self.ivar.
+  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
+    if (IVR->getSuperRegion() != SelfRegion)
+      return state;
+
+  QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
+  SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
+  return Bind(state, loc::MemRegionVal(R), V);
+}
+
index dc0cac887797b172e648d45f49359421657b9706..c533a7ec074ddced70c9cea8f8166e9cb1b62e0d 100644 (file)
@@ -244,6 +244,9 @@ public:
   // Binding values to regions.
   //===-------------------------------------------------------------------===//
 
+  const GRState *InvalidateRegion(const GRState *state, const MemRegion *R,
+                                  const Expr *E, unsigned Count);
+  
   const GRState *Bind(const GRState *state, Loc LV, SVal V);
 
   const GRState *BindCompoundLiteral(const GRState *state,
@@ -414,6 +417,103 @@ SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) {
   return M;
 }
 
+//===----------------------------------------------------------------------===//
+// Binding invalidation.
+//===----------------------------------------------------------------------===//
+
+const GRState *RegionStoreManager::InvalidateRegion(const GRState *state,
+                                                    const MemRegion *R,
+                                                    const Expr *E,
+                                                    unsigned Count) {
+  ASTContext& Ctx = StateMgr.getContext();
+  
+  if (!R->isBoundable())
+    return state;
+  
+  if (isa<AllocaRegion>(R) || isa<SymbolicRegion>(R) 
+      || isa<ObjCObjectRegion>(R)) {
+    // Invalidate the alloca region by setting its default value to 
+    // conjured symbol. The type of the symbol is irrelavant.
+    SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
+    state = setDefaultValue(state, R, V);
+    
+    // FIXME: This form of invalidation is a little bogus; we actually need
+    // to invalidate all subregions as well.
+    return state;
+  }
+  
+  const TypedRegion *TR = cast<TypedRegion>(R);
+  QualType T = TR->getValueType(Ctx);
+  
+  // FIXME: The code causes a crash when using RegionStore on the test case
+  // 'test_invalidate_cast_int' (misc-ps.m).  Consider removing it
+  // permanently.  Region casts are probably not too strict to handle
+  // the transient interpretation of memory.  Instead we can use the QualType
+  // passed to 'Retrieve' and friends to determine the most current
+  // interpretation of memory when it is actually used.
+#if 0
+  // If the region is cast to another type, use that type.  
+  if (const QualType *CastTy = getCastType(state, R)) {
+    assert(!(*CastTy)->isObjCObjectPointerType());
+    QualType NewT = (*CastTy)->getAsPointerType()->getPointeeType();    
+    
+    // The only exception is if the original region had a location type as its
+    // value type we always want to treat the region as binding to a location.
+    // This issue can arise when pointers are casted to integers and back.
+    
+    if (!(Loc::IsLocType(T) && !Loc::IsLocType(NewT)))
+      T = NewT;
+  }
+#endif
+  
+  if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
+    SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
+    return Bind(state, ValMgr.makeLoc(TR), V);
+  }
+  else if (const RecordType *RT = T->getAsStructureType()) {
+    // FIXME: handle structs with default region value.
+    const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx);
+    
+    // No record definition.  There is nothing we can do.
+    if (!RD)
+      return state;
+    
+    // Iterate through the fields and construct new symbols.
+    for (RecordDecl::field_iterator FI=RD->field_begin(),
+         FE=RD->field_end(); FI!=FE; ++FI) {
+      
+      // For now just handle scalar fields.
+      FieldDecl *FD = *FI;
+      QualType FT = FD->getType();
+      const FieldRegion* FR = MRMgr.getFieldRegion(FD, TR);
+      
+      if (Loc::IsLocType(FT) || 
+          (FT->isIntegerType() && FT->isScalarType())) {
+        SVal V = ValMgr.getConjuredSymbolVal(E, FT, Count);
+        state = state->bindLoc(ValMgr.makeLoc(FR), V);
+      }
+      else if (FT->isStructureType()) {
+        // set the default value of the struct field to conjured
+        // symbol. Note that the type of the symbol is irrelavant.
+        // We cannot use the type of the struct otherwise ValMgr won't
+        // give us the conjured symbol.
+        SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
+        state = setDefaultValue(state, FR, V);
+      }
+    }
+  } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
+    // Set the default value of the array to conjured symbol.
+    SVal V = ValMgr.getConjuredSymbolVal(E, AT->getElementType(),
+                                         Count);
+    state = setDefaultValue(state, TR, V);
+  } else {
+    // Just blast away other values.
+    state = Bind(state, ValMgr.makeLoc(TR), UnknownVal());
+  }
+  
+  return state;
+}
+
 //===----------------------------------------------------------------------===//
 // getLValueXXX methods.
 //===----------------------------------------------------------------------===//
index bddf05465aff5353429b7b0f77756404999edb5a..114942177cc79e89c68e8df13985f76210c51cdd 100644 (file)
@@ -234,95 +234,3 @@ StoreManager::OldCastRegion(const GRState* state, const MemRegion* R,
   
   return CastResult(state, R);
 }
-
-const GRState *StoreManager::InvalidateRegion(const GRState *state,
-                                              const MemRegion *R,
-                                              const Expr *E, unsigned Count) {
-  ASTContext& Ctx = StateMgr.getContext();
-
-  if (!R->isBoundable())
-    return state;
-
-  if (isa<AllocaRegion>(R) || isa<SymbolicRegion>(R) 
-      || isa<ObjCObjectRegion>(R)) {
-    // Invalidate the alloca region by setting its default value to 
-    // conjured symbol. The type of the symbol is irrelavant.
-    SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
-    state = setDefaultValue(state, R, V);
-    
-    // FIXME: This form of invalidation is a little bogus; we actually need
-    // to invalidate all subregions as well.
-    return state;
-  }
-
-  const TypedRegion *TR = cast<TypedRegion>(R);
-  QualType T = TR->getValueType(Ctx);
-
-  // FIXME: The code causes a crash when using RegionStore on the test case
-  // 'test_invalidate_cast_int' (misc-ps.m).  Consider removing it
-  // permanently.  Region casts are probably not too strict to handle
-  // the transient interpretation of memory.  Instead we can use the QualType
-  // passed to 'Retrieve' and friends to determine the most current
-  // interpretation of memory when it is actually used.
-#if 0
-  // If the region is cast to another type, use that type.  
-  if (const QualType *CastTy = getCastType(state, R)) {
-    assert(!(*CastTy)->isObjCObjectPointerType());
-    QualType NewT = (*CastTy)->getAsPointerType()->getPointeeType();    
-
-    // The only exception is if the original region had a location type as its
-    // value type we always want to treat the region as binding to a location.
-    // This issue can arise when pointers are casted to integers and back.
-
-    if (!(Loc::IsLocType(T) && !Loc::IsLocType(NewT)))
-      T = NewT;
-  }
-#endif
-  
-  if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
-    SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
-    return Bind(state, ValMgr.makeLoc(TR), V);
-  }
-  else if (const RecordType *RT = T->getAsStructureType()) {
-    // FIXME: handle structs with default region value.
-    const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx);
-
-    // No record definition.  There is nothing we can do.
-    if (!RD)
-      return state;
-
-    // Iterate through the fields and construct new symbols.
-    for (RecordDecl::field_iterator FI=RD->field_begin(),
-           FE=RD->field_end(); FI!=FE; ++FI) {
-      
-      // For now just handle scalar fields.
-      FieldDecl *FD = *FI;
-      QualType FT = FD->getType();
-      const FieldRegion* FR = MRMgr.getFieldRegion(FD, TR);
-      
-      if (Loc::IsLocType(FT) || 
-          (FT->isIntegerType() && FT->isScalarType())) {
-        SVal V = ValMgr.getConjuredSymbolVal(E, FT, Count);
-        state = state->bindLoc(ValMgr.makeLoc(FR), V);
-      }
-      else if (FT->isStructureType()) {
-        // set the default value of the struct field to conjured
-        // symbol. Note that the type of the symbol is irrelavant.
-        // We cannot use the type of the struct otherwise ValMgr won't
-        // give us the conjured symbol.
-        SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
-        state = setDefaultValue(state, FR, V);
-      }
-    }
-  } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
-    // Set the default value of the array to conjured symbol.
-    SVal V = ValMgr.getConjuredSymbolVal(E, AT->getElementType(),
-                                         Count);
-    state = setDefaultValue(state, TR, V);
-  } else {
-    // Just blast away other values.
-    state = Bind(state, ValMgr.makeLoc(TR), UnknownVal());
-  }
-  
-  return state;
-}