Make StoreManager::InvalidateRegion() virtual, move the current implementation
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
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index dc0cac8..c533a7e 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -244,6 +244,9 @@
// 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,
@@ -415,6 +418,103 @@
}
//===----------------------------------------------------------------------===//
+// 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.
//===----------------------------------------------------------------------===//