Refactor 'BasicStoreManager::CastRegion' and 'RegionStoreManager::CastRegion'
into StoreManager::CastRegion. Both methods were practically identical, and this is core logic that is common to all StoreManagers since it defines the basic invariants of the abstract memory model. llvm-svn: 69730
This commit is contained in:
parent
6750113d54
commit
2d495a6f43
|
@ -37,13 +37,20 @@ class SubRegionMap;
|
|||
class StoreManager {
|
||||
protected:
|
||||
ValueManager &ValMgr;
|
||||
GRStateManager &StateMgr;
|
||||
|
||||
/// MRMgr - Manages region objects associated with this StoreManager.
|
||||
MemRegionManager &MRMgr;
|
||||
|
||||
StoreManager(ValueManager &valMgr)
|
||||
: ValMgr(valMgr), MRMgr(ValMgr.getRegionManager()) {}
|
||||
StoreManager(GRStateManager &stateMgr);
|
||||
|
||||
protected:
|
||||
virtual const GRState* AddRegionView(const GRState* St,
|
||||
const MemRegion* View,
|
||||
const MemRegion* Base) {
|
||||
return St;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~StoreManager() {}
|
||||
|
||||
|
@ -125,8 +132,8 @@ public:
|
|||
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
|
||||
/// a MemRegion* to a specific location type. 'R' is the region being
|
||||
/// casted and 'CastToTy' the result type of the cast.
|
||||
virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy) = 0;
|
||||
CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy);
|
||||
|
||||
/// EvalBinOp - Perform pointer arithmetic.
|
||||
virtual SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
|
||||
|
|
|
@ -35,14 +35,12 @@ public:
|
|||
|
||||
class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
|
||||
BindingsTy::Factory VBFactory;
|
||||
GRStateManager& StateMgr;
|
||||
const MemRegion* SelfRegion;
|
||||
|
||||
public:
|
||||
BasicStoreManager(GRStateManager& mgr)
|
||||
: StoreManager(mgr.getValueManager()),
|
||||
: StoreManager(mgr),
|
||||
VBFactory(mgr.getAllocator()),
|
||||
StateMgr(mgr),
|
||||
SelfRegion(0) {}
|
||||
|
||||
~BasicStoreManager() {}
|
||||
|
@ -87,12 +85,6 @@ public:
|
|||
/// conversions between arrays and pointers.
|
||||
SVal ArrayToPointer(Loc Array) { return Array; }
|
||||
|
||||
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
|
||||
/// a MemRegion* to a specific location type. 'R' is the region being
|
||||
/// casted and 'CastToTy' the result type of the cast.
|
||||
CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy);
|
||||
|
||||
/// getSelfRegion - Returns the region for the 'self' (Objective-C) or
|
||||
/// 'this' object (C++). When used when analyzing a normal function this
|
||||
/// method returns NULL.
|
||||
|
@ -168,27 +160,7 @@ SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
|
|||
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
|
||||
/// a MemRegion* to a specific location type. 'R' is the region being
|
||||
/// casted and 'CastToTy' the result type of the cast.
|
||||
StoreManager::CastResult
|
||||
BasicStoreManager::CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy) {
|
||||
|
||||
// Return the same region if the region types are compatible.
|
||||
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
|
||||
ASTContext& Ctx = StateMgr.getContext();
|
||||
QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx));
|
||||
QualType Tb = Ctx.getCanonicalType(CastToTy);
|
||||
|
||||
if (Ta == Tb)
|
||||
return CastResult(state, R);
|
||||
}
|
||||
|
||||
return CastResult(state, MRMgr.getTypedViewRegion(CastToTy, R));
|
||||
}
|
||||
|
||||
SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base,
|
||||
const FieldDecl* D) {
|
||||
|
||||
|
|
|
@ -142,16 +142,15 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
|
|||
RegionBindingsTy::Factory RBFactory;
|
||||
RegionViews::Factory RVFactory;
|
||||
|
||||
GRStateManager& StateMgr;
|
||||
const MemRegion* SelfRegion;
|
||||
const ImplicitParamDecl *SelfDecl;
|
||||
|
||||
public:
|
||||
RegionStoreManager(GRStateManager& mgr)
|
||||
: StoreManager(mgr.getValueManager()),
|
||||
: StoreManager(mgr),
|
||||
RBFactory(mgr.getAllocator()),
|
||||
RVFactory(mgr.getAllocator()),
|
||||
StateMgr(mgr), SelfRegion(0), SelfDecl(0) {
|
||||
SelfRegion(0), SelfDecl(0) {
|
||||
if (const ObjCMethodDecl* MD =
|
||||
dyn_cast<ObjCMethodDecl>(&StateMgr.getCodeDecl()))
|
||||
SelfDecl = MD->getSelfDecl();
|
||||
|
@ -199,12 +198,6 @@ public:
|
|||
/// casts from arrays to pointers.
|
||||
SVal ArrayToPointer(Loc Array);
|
||||
|
||||
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
|
||||
/// a MemRegion* to a specific location type. 'R' is the region being
|
||||
/// casted and 'CastToTy' the result type of the cast.
|
||||
CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy);
|
||||
|
||||
SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R);
|
||||
|
||||
/// The high level logic for this method is this:
|
||||
|
@ -579,31 +572,6 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
|
|||
return loc::MemRegionVal(ER);
|
||||
}
|
||||
|
||||
StoreManager::CastResult
|
||||
RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy) {
|
||||
|
||||
// Return the same region if the region types are compatible.
|
||||
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
|
||||
ASTContext& Ctx = StateMgr.getContext();
|
||||
QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx));
|
||||
QualType Tb = Ctx.getCanonicalType(CastToTy);
|
||||
|
||||
if (Ta == Tb)
|
||||
return CastResult(state, R);
|
||||
}
|
||||
|
||||
// FIXME: We should handle the case when we are casting *back* to a
|
||||
// previous type. For example:
|
||||
//
|
||||
// void* x = ...;
|
||||
// char* y = (char*) x;
|
||||
// void* z = (void*) y; // <-- we should get the same region that is
|
||||
// bound to 'x'
|
||||
const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R);
|
||||
return CastResult(AddRegionView(state, ViewR, R), ViewR);
|
||||
}
|
||||
|
||||
SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
|
||||
// Assume the base location is MemRegionVal(ElementRegion).
|
||||
if (!isa<loc::MemRegionVal>(L))
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defined the types Store and StoreManager.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/Store.h"
|
||||
#include "clang/Analysis/PathSensitive/GRState.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
StoreManager::StoreManager(GRStateManager &stateMgr)
|
||||
: ValMgr(stateMgr.getValueManager()),
|
||||
StateMgr(stateMgr),
|
||||
MRMgr(ValMgr.getRegionManager()) {}
|
||||
|
||||
StoreManager::CastResult
|
||||
StoreManager::CastRegion(const GRState* state, const MemRegion* R,
|
||||
QualType CastToTy) {
|
||||
|
||||
// Return the same region if the region types are compatible.
|
||||
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
|
||||
ASTContext& Ctx = StateMgr.getContext();
|
||||
QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx));
|
||||
QualType Tb = Ctx.getCanonicalType(CastToTy);
|
||||
|
||||
if (Ta == Tb)
|
||||
return CastResult(state, R);
|
||||
}
|
||||
|
||||
// FIXME: We should handle the case when we are casting *back* to a
|
||||
// previous type. For example:
|
||||
//
|
||||
// void* x = ...;
|
||||
// char* y = (char*) x;
|
||||
// void* z = (void*) y; // <-- we should get the same region that is
|
||||
// bound to 'x'
|
||||
const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R);
|
||||
return CastResult(AddRegionView(state, ViewR, R), ViewR);
|
||||
}
|
Loading…
Reference in New Issue