diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-07-29 18:16:25 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-07-29 18:16:25 +0000 |
commit | 1004a9f2b9eaf885e55ad8656194ef2a341db0f5 (patch) | |
tree | 03f7509b0df6a4b6459be7381fda1cae8bd75679 /lib/Analysis/RegionStore.cpp | |
parent | 0e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2 (diff) |
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
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index dc0cac8877..c533a7ec07 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -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, @@ -415,6 +418,103 @@ SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) { } //===----------------------------------------------------------------------===// +// 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. //===----------------------------------------------------------------------===// |