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) {
}
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));
}
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);
+}
+
// 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,
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.
//===----------------------------------------------------------------------===//
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;
-}