[analyzer] Rename Store::Retrieve() -> getBinding().

+ all the other Retrieve..() methods + a comment for ElementRegion.

llvm-svn: 148011
This commit is contained in:
Anna Zaks 2012-01-12 02:22:40 +00:00
parent b3fa8d7dd1
commit 95f332112f
6 changed files with 74 additions and 67 deletions

View File

@ -887,6 +887,7 @@ public:
void dump() const; void dump() const;
}; };
/// \brief ElementRegin is used to represent both array elements and casts.
class ElementRegion : public TypedValueRegion { class ElementRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;

View File

@ -728,11 +728,12 @@ ProgramState::getSValAsScalarOrLoc(const Stmt *S,
} }
inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const { inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
return getStateManager().StoreMgr->Retrieve(getStore(), LV, T); return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
} }
inline SVal ProgramState::getSVal(const MemRegion* R) const { inline SVal ProgramState::getSVal(const MemRegion* R) const {
return getStateManager().StoreMgr->Retrieve(getStore(), loc::MemRegionVal(R)); return getStateManager().StoreMgr->getBinding(getStore(),
loc::MemRegionVal(R));
} }
inline BasicValueFactory &ProgramState::getBasicVals() const { inline BasicValueFactory &ProgramState::getBasicVals() const {

View File

@ -55,7 +55,7 @@ public:
/// expected type of the returned value. This is used if the value is /// expected type of the returned value. This is used if the value is
/// lazily computed. /// lazily computed.
/// \return The value bound to the location \c loc. /// \return The value bound to the location \c loc.
virtual SVal Retrieve(Store store, Loc loc, QualType T = QualType()) = 0; virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
/// Return a state with the specified value bound to the given location. /// Return a state with the specified value bound to the given location.
/// \param[in] state The analysis state. /// \param[in] state The analysis state.

View File

@ -133,7 +133,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
return true; return true;
} }
else { else {
const SVal &V = StoreMgr.Retrieve(store, loc::MemRegionVal(FR)); const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
if (V.isUndef()) if (V.isUndef())
return true; return true;
} }

View File

@ -224,7 +224,7 @@ static SymbolRef getAsPointeeSymbol(const Expr *Expr,
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) { if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
StoreManager& SM = C.getStoreManager(); StoreManager& SM = C.getStoreManager();
const MemRegion *V = SM.Retrieve(State->getStore(), *X).getAsRegion(); const MemRegion *V = SM.getBinding(State->getStore(), *X).getAsRegion();
if (V) if (V)
return getSymbolForRegion(C, V); return getSymbolForRegion(C, V);
} }

View File

@ -279,7 +279,8 @@ public: // Part of public interface to class.
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
assert(!lookup(B, R, BindingKey::Default)); assert(!lookup(B, R, BindingKey::Default));
assert(!lookup(B, R, BindingKey::Direct)); assert(!lookup(B, R, BindingKey::Direct));
return StoreRef(addBinding(B, R, BindingKey::Default, V).getRootWithoutRetain(), *this); return StoreRef(addBinding(B, R, BindingKey::Default, V)
.getRootWithoutRetain(), *this);
} }
StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr *CL, StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr *CL,
@ -314,12 +315,10 @@ public: // Part of public interface to class.
bool includedInBindings(Store store, const MemRegion *region) const; bool includedInBindings(Store store, const MemRegion *region) const;
//===------------------------------------------------------------------===// /// \brief Return the value bound to specified location in a given state.
// Loading values from regions. ///
//===------------------------------------------------------------------===//
/// The high level logic for this method is this: /// The high level logic for this method is this:
/// Retrieve (L) /// getBinding (L)
/// if L has binding /// if L has binding
/// return L's binding /// return L's binding
/// else if L is in killset /// else if L is in killset
@ -329,39 +328,39 @@ public: // Part of public interface to class.
/// return undefined /// return undefined
/// else /// else
/// return symbolic /// return symbolic
SVal Retrieve(Store store, Loc L, QualType T = QualType()); SVal getBinding(Store store, Loc L, QualType T = QualType());
SVal RetrieveElement(Store store, const ElementRegion *R); SVal getBindingForElement(Store store, const ElementRegion *R);
SVal RetrieveField(Store store, const FieldRegion *R); SVal getBindingForField(Store store, const FieldRegion *R);
SVal RetrieveObjCIvar(Store store, const ObjCIvarRegion *R); SVal getBindingForObjCIvar(Store store, const ObjCIvarRegion *R);
SVal RetrieveVar(Store store, const VarRegion *R); SVal getBindingForVar(Store store, const VarRegion *R);
SVal RetrieveLazySymbol(const TypedValueRegion *R); SVal getBindingForLazySymbol(const TypedValueRegion *R);
SVal RetrieveFieldOrElementCommon(Store store, const TypedValueRegion *R, SVal getBindingForFieldOrElementCommon(Store store, const TypedValueRegion *R,
QualType Ty, const MemRegion *superR); QualType Ty, const MemRegion *superR);
SVal RetrieveLazyBinding(const MemRegion *lazyBindingRegion, SVal getLazyBinding(const MemRegion *lazyBindingRegion,
Store lazyBindingStore); Store lazyBindingStore);
/// Retrieve the values in a struct and return a CompoundVal, used when doing /// Get bindings for the values in a struct and return a CompoundVal, used
/// struct copy: /// when doing struct copy:
/// struct s x, y; /// struct s x, y;
/// x = y; /// x = y;
/// y's value is retrieved by this method. /// y's value is retrieved by this method.
SVal RetrieveStruct(Store store, const TypedValueRegion* R); SVal getBindingForStruct(Store store, const TypedValueRegion* R);
SVal RetrieveArray(Store store, const TypedValueRegion* R); SVal getBindingForArray(Store store, const TypedValueRegion* R);
/// Used to lazily generate derived symbols for bindings that are defined /// Used to lazily generate derived symbols for bindings that are defined
/// implicitly by default bindings in a super region. /// implicitly by default bindings in a super region.
Optional<SVal> RetrieveDerivedDefaultValue(RegionBindings B, Optional<SVal> getBindingForDerivedDefaultValue(RegionBindings B,
const MemRegion *superR, const MemRegion *superR,
const TypedValueRegion *R, const TypedValueRegion *R,
QualType Ty); QualType Ty);
/// Get the state and region whose binding this region R corresponds to. /// Get the state and region whose binding this region R corresponds to.
std::pair<Store, const MemRegion*> std::pair<Store, const MemRegion*>
@ -428,7 +427,8 @@ StoreManager *ento::CreateRegionStoreManager(ProgramStateManager& StMgr) {
return new RegionStoreManager(StMgr, F); return new RegionStoreManager(StMgr, F);
} }
StoreManager *ento::CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr) { StoreManager *
ento::CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr) {
RegionStoreFeatures F = minimal_features_tag(); RegionStoreFeatures F = minimal_features_tag();
F.enableFields(true); F.enableFields(true);
return new RegionStoreManager(StMgr, F); return new RegionStoreManager(StMgr, F);
@ -719,7 +719,7 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
} }
DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, T, Count); DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, T,Count);
assert(SymbolManager::canSymbolicate(T) || V.isUnknown()); assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
B = RM.addBinding(B, baseR, BindingKey::Direct, V); B = RM.addBinding(B, baseR, BindingKey::Direct, V);
} }
@ -794,9 +794,10 @@ StoreRef RegionStoreManager::invalidateRegions(Store store,
// Extents for regions. // Extents for regions.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const ProgramState *state, DefinedOrUnknownSVal
const MemRegion *R, RegionStoreManager::getSizeInElements(const ProgramState *state,
QualType EleTy) { const MemRegion *R,
QualType EleTy) {
SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder); SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size); const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
if (!SizeInt) if (!SizeInt)
@ -893,7 +894,7 @@ Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
return Optional<SVal>(); return Optional<SVal>();
} }
SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) { SVal RegionStoreManager::getBinding(Store store, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown"); assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined"); assert(!isa<UndefinedVal>(L) && "location undefined");
@ -937,21 +938,21 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// Such funny addressing will occur due to layering of regions. // Such funny addressing will occur due to layering of regions.
if (RTy->isStructureOrClassType()) if (RTy->isStructureOrClassType())
return RetrieveStruct(store, R); return getBindingForStruct(store, R);
// FIXME: Handle unions. // FIXME: Handle unions.
if (RTy->isUnionType()) if (RTy->isUnionType())
return UnknownVal(); return UnknownVal();
if (RTy->isArrayType()) if (RTy->isArrayType())
return RetrieveArray(store, R); return getBindingForArray(store, R);
// FIXME: handle Vector types. // FIXME: handle Vector types.
if (RTy->isVectorType()) if (RTy->isVectorType())
return UnknownVal(); return UnknownVal();
if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
return CastRetrievedVal(RetrieveField(store, FR), FR, T, false); return CastRetrievedVal(getBindingForField(store, FR), FR, T, false);
if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) { if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
// FIXME: Here we actually perform an implicit conversion from the loaded // FIXME: Here we actually perform an implicit conversion from the loaded
@ -959,7 +960,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// more intelligently. For example, an 'element' can encompass multiple // more intelligently. For example, an 'element' can encompass multiple
// bound regions (e.g., several bound bytes), or could be a subset of // bound regions (e.g., several bound bytes), or could be a subset of
// a larger value. // a larger value.
return CastRetrievedVal(RetrieveElement(store, ER), ER, T, false); return CastRetrievedVal(getBindingForElement(store, ER), ER, T, false);
} }
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) { if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
@ -969,7 +970,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// reinterpretted, it is possible we stored a different value that could // reinterpretted, it is possible we stored a different value that could
// fit within the ivar. Either we need to cast these when storing them // fit within the ivar. Either we need to cast these when storing them
// or reinterpret them lazily (as we do here). // or reinterpret them lazily (as we do here).
return CastRetrievedVal(RetrieveObjCIvar(store, IVR), IVR, T, false); return CastRetrievedVal(getBindingForObjCIvar(store, IVR), IVR, T, false);
} }
if (const VarRegion *VR = dyn_cast<VarRegion>(R)) { if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
@ -979,7 +980,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// variable is reinterpretted, it is possible we stored a different value // variable is reinterpretted, it is possible we stored a different value
// that could fit within the variable. Either we need to cast these when // that could fit within the variable. Either we need to cast these when
// storing them or reinterpret them lazily (as we do here). // storing them or reinterpret them lazily (as we do here).
return CastRetrievedVal(RetrieveVar(store, VR), VR, T, false); return CastRetrievedVal(getBindingForVar(store, VR), VR, T, false);
} }
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
@ -1049,7 +1050,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R,
return std::make_pair((Store) 0, (const MemRegion *) 0); return std::make_pair((Store) 0, (const MemRegion *) 0);
} }
SVal RegionStoreManager::RetrieveElement(Store store, SVal RegionStoreManager::getBindingForElement(Store store,
const ElementRegion* R) { const ElementRegion* R) {
// Check if the region has a binding. // Check if the region has a binding.
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
@ -1071,7 +1072,7 @@ SVal RegionStoreManager::RetrieveElement(Store store,
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
int64_t i = CI->getValue().getSExtValue(); int64_t i = CI->getValue().getSExtValue();
// Abort on string underrun. This can be possible by arbitrary // Abort on string underrun. This can be possible by arbitrary
// clients of RetrieveElement(). // clients of getBindingForElement().
if (i < 0) if (i < 0)
return UndefinedVal(); return UndefinedVal();
int64_t length = Str->getLength(); int64_t length = Str->getLength();
@ -1121,10 +1122,11 @@ SVal RegionStoreManager::RetrieveElement(Store store,
} }
} }
} }
return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR); return getBindingForFieldOrElementCommon(store, R, R->getElementType(),
superR);
} }
SVal RegionStoreManager::RetrieveField(Store store, SVal RegionStoreManager::getBindingForField(Store store,
const FieldRegion* R) { const FieldRegion* R) {
// Check if the region has a binding. // Check if the region has a binding.
@ -1133,14 +1135,14 @@ SVal RegionStoreManager::RetrieveField(Store store,
return *V; return *V;
QualType Ty = R->getValueType(); QualType Ty = R->getValueType();
return RetrieveFieldOrElementCommon(store, R, Ty, R->getSuperRegion()); return getBindingForFieldOrElementCommon(store, R, Ty, R->getSuperRegion());
} }
Optional<SVal> Optional<SVal>
RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B, RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindings B,
const MemRegion *superR, const MemRegion *superR,
const TypedValueRegion *R, const TypedValueRegion *R,
QualType Ty) { QualType Ty) {
if (const Optional<SVal> &D = getDefaultBinding(B, superR)) { if (const Optional<SVal> &D = getDefaultBinding(B, superR)) {
const SVal &val = D.getValue(); const SVal &val = D.getValue();
@ -1163,28 +1165,28 @@ RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B,
return Optional<SVal>(); return Optional<SVal>();
} }
SVal RegionStoreManager::RetrieveLazyBinding(const MemRegion *lazyBindingRegion, SVal RegionStoreManager::getLazyBinding(const MemRegion *lazyBindingRegion,
Store lazyBindingStore) { Store lazyBindingStore) {
if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion)) if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))
return RetrieveElement(lazyBindingStore, ER); return getBindingForElement(lazyBindingStore, ER);
return RetrieveField(lazyBindingStore, return getBindingForField(lazyBindingStore,
cast<FieldRegion>(lazyBindingRegion)); cast<FieldRegion>(lazyBindingRegion));
} }
SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store, SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store,
const TypedValueRegion *R, const TypedValueRegion *R,
QualType Ty, QualType Ty,
const MemRegion *superR) { const MemRegion *superR) {
// At this point we have already checked in either RetrieveElement or // At this point we have already checked in either getBindingForElement or
// RetrieveField if 'R' has a direct binding. // getBindingForField if 'R' has a direct binding.
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
while (superR) { while (superR) {
if (const Optional<SVal> &D = if (const Optional<SVal> &D =
RetrieveDerivedDefaultValue(B, superR, R, Ty)) getBindingForDerivedDefaultValue(B, superR, R, Ty))
return *D; return *D;
// If our super region is a field or element itself, walk up the region // If our super region is a field or element itself, walk up the region
@ -1202,7 +1204,7 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R); llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R);
if (lazyBindingRegion) if (lazyBindingRegion)
return RetrieveLazyBinding(lazyBindingRegion, lazyBindingStore); return getLazyBinding(lazyBindingRegion, lazyBindingStore);
if (R->hasStackNonParametersStorage()) { if (R->hasStackNonParametersStorage()) {
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
@ -1227,7 +1229,8 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
return svalBuilder.getRegionValueSymbolVal(R); return svalBuilder.getRegionValueSymbolVal(R);
} }
SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){ SVal RegionStoreManager::getBindingForObjCIvar(Store store,
const ObjCIvarRegion* R) {
// Check if the region has a binding. // Check if the region has a binding.
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
@ -1246,10 +1249,10 @@ SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){
return UnknownVal(); return UnknownVal();
} }
return RetrieveLazySymbol(R); return getBindingForLazySymbol(R);
} }
SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) { SVal RegionStoreManager::getBindingForVar(Store store, const VarRegion *R) {
// Check if the region has a binding. // Check if the region has a binding.
RegionBindings B = GetRegionBindings(store); RegionBindings B = GetRegionBindings(store);
@ -1281,7 +1284,8 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
} }
} }
if (const Optional<SVal> &V = RetrieveDerivedDefaultValue(B, MS, R, CT)) if (const Optional<SVal> &V
= getBindingForDerivedDefaultValue(B, MS, R, CT))
return V.getValue(); return V.getValue();
return svalBuilder.getRegionValueSymbolVal(R); return svalBuilder.getRegionValueSymbolVal(R);
@ -1298,19 +1302,19 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
return UndefinedVal(); return UndefinedVal();
} }
SVal RegionStoreManager::RetrieveLazySymbol(const TypedValueRegion *R) { SVal RegionStoreManager::getBindingForLazySymbol(const TypedValueRegion *R) {
// All other values are symbolic. // All other values are symbolic.
return svalBuilder.getRegionValueSymbolVal(R); return svalBuilder.getRegionValueSymbolVal(R);
} }
SVal RegionStoreManager::RetrieveStruct(Store store, SVal RegionStoreManager::getBindingForStruct(Store store,
const TypedValueRegion* R) { const TypedValueRegion* R) {
QualType T = R->getValueType(); QualType T = R->getValueType();
assert(T->isStructureOrClassType()); assert(T->isStructureOrClassType());
return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R); return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);
} }
SVal RegionStoreManager::RetrieveArray(Store store, SVal RegionStoreManager::getBindingForArray(Store store,
const TypedValueRegion * R) { const TypedValueRegion * R) {
assert(Ctx.getAsConstantArrayType(R->getValueType())); assert(Ctx.getAsConstantArrayType(R->getValueType()));
return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R); return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);
@ -1674,7 +1678,8 @@ class removeDeadBindingsWorker :
const StackFrameContext *CurrentLCtx; const StackFrameContext *CurrentLCtx;
public: public:
removeDeadBindingsWorker(RegionStoreManager &rm, ProgramStateManager &stateMgr, removeDeadBindingsWorker(RegionStoreManager &rm,
ProgramStateManager &stateMgr,
RegionBindings b, SymbolReaper &symReaper, RegionBindings b, SymbolReaper &symReaper,
const StackFrameContext *LCtx) const StackFrameContext *LCtx)
: ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b, : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b,