зеркало из https://github.com/microsoft/clang-1.git
- constify some uses of MemRegion* (MemRegion should be immutable).
- Added new region "SymbolicRegion", which maps symbol values to the region domain. - Enhanced BasicStore::getFieldLValue() to return a FieldRegion (using SymbolicRegion) - Added some utility methods to GRState for fetch svals from the store. - Fixed regression in CheckNSError (we weren't getting the value bound to the parameter) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57717 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0d504c1da8
Коммит
993f1c7291
|
@ -425,6 +425,10 @@ public:
|
|||
return StoreMgr->GetSVal(St->getStore(), LV, T);
|
||||
}
|
||||
|
||||
SVal GetSVal(const GRState* St, const MemRegion* R) {
|
||||
return StoreMgr->GetRegionSVal(St->getStore(), R);
|
||||
}
|
||||
|
||||
void SetSVal(GRState& St, Loc LV, SVal V) {
|
||||
St.St = StoreMgr->SetSVal(St.St, LV, V);
|
||||
}
|
||||
|
@ -522,6 +526,10 @@ public:
|
|||
return Mgr->GetSVal(St, LV, T);
|
||||
}
|
||||
|
||||
SVal GetSVal(const MemRegion* R) {
|
||||
return Mgr->GetSVal(St, R);
|
||||
}
|
||||
|
||||
GRStateRef SetSVal(Expr* Ex, SVal V, bool isBlkExpr, bool Invalidate) {
|
||||
return GRStateRef(Mgr->SetSVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
|
||||
}
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H
|
||||
#define LLVM_CLANG_ANALYSIS_MEMREGION_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm { class raw_ostream; }
|
||||
|
@ -33,7 +34,7 @@ class MemRegionManager;
|
|||
/// MemRegion - The root abstract class for all memory regions.
|
||||
class MemRegion : public llvm::FoldingSetNode {
|
||||
public:
|
||||
enum Kind { MemSpaceRegionKind,
|
||||
enum Kind { MemSpaceRegionKind, SymbolicRegionKind,
|
||||
// Typed regions.
|
||||
BEG_TYPED_REGIONS,
|
||||
VarRegionKind, FieldRegionKind, ObjCIvarRegionKind,
|
||||
|
@ -48,7 +49,6 @@ protected:
|
|||
|
||||
public:
|
||||
// virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
|
||||
virtual const MemRegion* getSuperRegion() const = 0;
|
||||
virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
|
||||
|
||||
std::string getString() const;
|
||||
|
@ -67,11 +67,6 @@ class MemSpaceRegion : public MemRegion {
|
|||
public:
|
||||
//RegionExtent getExtent() const { return UndefinedExtent(); }
|
||||
|
||||
const MemRegion* getSuperRegion() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//static void ProfileRegion(llvm::FoldingSetNodeID& ID);
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const;
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
|
@ -79,22 +74,57 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// TypedRegion - An abstract class representing regions that are typed.
|
||||
class TypedRegion : public MemRegion {
|
||||
/// SubRegion - A region that subsets another larger region. Most regions
|
||||
/// are subclasses of SubRegion.
|
||||
class SubRegion : public MemRegion {
|
||||
protected:
|
||||
const MemRegion* superRegion;
|
||||
|
||||
TypedRegion(const MemRegion* sReg, Kind k)
|
||||
: MemRegion(k), superRegion(sReg) {};
|
||||
const MemRegion* superRegion;
|
||||
SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
|
||||
|
||||
public:
|
||||
virtual QualType getType() const = 0;
|
||||
|
||||
// MemExtent getExtent(MemRegionManager& mrm) const;
|
||||
const MemRegion* getSuperRegion() const {
|
||||
return superRegion;
|
||||
}
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() > SymbolicRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
|
||||
/// clases, SymbolicRegion represents a region that serves as an alias for
|
||||
/// either a real region, a NULL pointer, etc. It essentially is used to
|
||||
/// map the concept of symbolic values into the domain of regions. Symbolic
|
||||
/// regions do not need to be typed.
|
||||
class SymbolicRegion : public MemRegion {
|
||||
protected:
|
||||
const SymbolID sym;
|
||||
|
||||
public:
|
||||
SymbolicRegion(const SymbolID s) : MemRegion(SymbolicRegionKind), sym(s) {}
|
||||
|
||||
SymbolID getSymbol() const {
|
||||
return sym;
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const;
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym);
|
||||
|
||||
void print(llvm::raw_ostream& os) const;
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() == SymbolicRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// TypedRegion - An abstract class representing regions that are typed.
|
||||
class TypedRegion : public SubRegion {
|
||||
protected:
|
||||
TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
|
||||
|
||||
public:
|
||||
virtual QualType getType() const = 0;
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
unsigned k = R->getKind();
|
||||
return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
|
||||
|
@ -152,7 +182,7 @@ class DeclRegion : public TypedRegion {
|
|||
protected:
|
||||
const Decl* D;
|
||||
|
||||
DeclRegion(const Decl* d, MemRegion* sReg, Kind k)
|
||||
DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
|
||||
: TypedRegion(sReg, k), D(d) {}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
|
||||
|
@ -165,7 +195,7 @@ public:
|
|||
class VarRegion : public DeclRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
VarRegion(const VarDecl* vd, MemRegion* sReg)
|
||||
VarRegion(const VarDecl* vd, const MemRegion* sReg)
|
||||
: DeclRegion(vd, sReg, VarRegionKind) {}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, VarDecl* VD,
|
||||
|
@ -187,7 +217,7 @@ public:
|
|||
class FieldRegion : public DeclRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
FieldRegion(const FieldDecl* fd, MemRegion* sReg)
|
||||
FieldRegion(const FieldDecl* fd, const MemRegion* sReg)
|
||||
: DeclRegion(fd, sReg, FieldRegionKind) {}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, FieldDecl* FD,
|
||||
|
@ -208,7 +238,7 @@ class ObjCIvarRegion : public DeclRegion {
|
|||
|
||||
friend class MemRegionManager;
|
||||
|
||||
ObjCIvarRegion(const ObjCIvarDecl* ivd, MemRegion* sReg)
|
||||
ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
|
||||
: DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCIvarDecl* ivd,
|
||||
|
@ -260,10 +290,13 @@ public:
|
|||
/// memory space.
|
||||
MemSpaceRegion* getUnknownRegion();
|
||||
|
||||
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
|
||||
SymbolicRegion* getSymbolicRegion(const SymbolID sym);
|
||||
|
||||
/// getVarRegion - Retrieve or create the memory region associated with
|
||||
/// a specified VarDecl. 'superRegion' corresponds to the containing
|
||||
/// memory region, and 'off' is the offset within the containing region.
|
||||
VarRegion* getVarRegion(const VarDecl* vd, MemRegion* superRegion);
|
||||
VarRegion* getVarRegion(const VarDecl* vd, const MemRegion* superRegion);
|
||||
|
||||
VarRegion* getVarRegion(const VarDecl* vd) {
|
||||
return getVarRegion(vd, vd->hasLocalStorage() ? getStackRegion()
|
||||
|
@ -274,14 +307,14 @@ public:
|
|||
/// a specified FieldDecl. 'superRegion' corresponds to the containing
|
||||
/// memory region (which typically represents the memory representing
|
||||
/// a structure or class).
|
||||
FieldRegion* getFieldRegion(const FieldDecl* fd, MemRegion* superRegion);
|
||||
FieldRegion* getFieldRegion(const FieldDecl* fd, const MemRegion* superRegion);
|
||||
|
||||
/// getObjCIvarRegion - Retrieve or create the memory region associated with
|
||||
/// a specified Objective-c instance variable. 'superRegion' corresponds
|
||||
/// to the containing region (which typically represents the Objective-C
|
||||
/// object).
|
||||
ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
|
||||
MemRegion* superRegion);
|
||||
const MemRegion* superRegion);
|
||||
|
||||
AnonPointeeRegion* getAnonPointeeRegion(const VarDecl* d);
|
||||
|
||||
|
|
|
@ -331,10 +331,15 @@ class MemRegionVal : public Loc {
|
|||
public:
|
||||
MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
|
||||
|
||||
MemRegion* getRegion() const {
|
||||
const MemRegion* getRegion() const {
|
||||
return static_cast<MemRegion*>(Data);
|
||||
}
|
||||
|
||||
template <typename REGION>
|
||||
const REGION* getRegionAs() const {
|
||||
return llvm::dyn_cast<REGION>(getRegion());
|
||||
}
|
||||
|
||||
inline bool operator==(const MemRegionVal& R) const {
|
||||
return getRegion() == R.getRegion();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define LLVM_CLANG_ANALYSIS_STORE_H
|
||||
|
||||
#include "clang/Analysis/PathSensitive/RValues.h"
|
||||
#include "clang/Analysis/PathSensitive/MemRegion.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
|
@ -31,8 +32,6 @@ class LiveVariables;
|
|||
class Stmt;
|
||||
class Expr;
|
||||
class ObjCIvarDecl;
|
||||
class MemRegion;
|
||||
class MemRegionManager;
|
||||
|
||||
class StoreManager {
|
||||
public:
|
||||
|
@ -40,7 +39,12 @@ public:
|
|||
typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
|
||||
|
||||
virtual ~StoreManager() {}
|
||||
virtual SVal GetSVal(Store St, Loc LV, QualType T = QualType()) = 0;
|
||||
virtual SVal GetSVal(Store St, Loc LV, QualType T = QualType()) = 0;
|
||||
|
||||
virtual SVal GetRegionSVal(Store St, const MemRegion* R) {
|
||||
return GetSVal(St, loc::MemRegionVal(R));
|
||||
}
|
||||
|
||||
virtual Store SetSVal(Store St, Loc LV, SVal V) = 0;
|
||||
virtual Store Remove(Store St, Loc LV) = 0;
|
||||
virtual Store getInitialStore() = 0;
|
||||
|
|
|
@ -367,7 +367,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void AddError(TypedRegion* R, Expr* Ex, ExplodedNode<GRState> *N,
|
||||
void AddError(const TypedRegion* R, Expr* Ex, ExplodedNode<GRState> *N,
|
||||
uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
@ -503,7 +503,7 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
|
|||
if (!LV)
|
||||
return false;
|
||||
|
||||
TypedRegion* R = dyn_cast<TypedRegion>(LV->getRegion());
|
||||
const TypedRegion* R = dyn_cast<TypedRegion>(LV->getRegion());
|
||||
if (!R)
|
||||
return false;
|
||||
|
||||
|
@ -530,7 +530,7 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
|
|||
return SourceSize < TargetSize;
|
||||
}
|
||||
|
||||
void AuditCFNumberCreate::AddError(TypedRegion* R, Expr* Ex,
|
||||
void AuditCFNumberCreate::AddError(const TypedRegion* R, Expr* Ex,
|
||||
ExplodedNode<GRState> *N,
|
||||
uint64_t SourceSize, uint64_t TargetSize,
|
||||
uint64_t NumberKind) {
|
||||
|
|
|
@ -90,7 +90,41 @@ SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
|
|||
|
||||
SVal BasicStoreManager::getLValueField(const GRState* St, const FieldDecl* D,
|
||||
SVal Base) {
|
||||
return UnknownVal();
|
||||
|
||||
if (Base.isUnknownOrUndef())
|
||||
return Base;
|
||||
|
||||
Loc BaseL = cast<Loc>(Base);
|
||||
const MemRegion* BaseR = 0;
|
||||
|
||||
switch(BaseL.getSubKind()) {
|
||||
case loc::SymbolValKind:
|
||||
BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol());
|
||||
break;
|
||||
|
||||
case loc::GotoLabelKind:
|
||||
case loc::FuncValKind:
|
||||
// Technically we can get here if people do funny things with casts.
|
||||
return UndefinedVal();
|
||||
|
||||
case loc::MemRegionKind:
|
||||
BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
|
||||
break;
|
||||
|
||||
case loc::ConcreteIntKind:
|
||||
case loc::StringLiteralValKind:
|
||||
// While these seem funny, this can happen through casts.
|
||||
// FIXME: What we should return is the field offset. For example,
|
||||
// add the field offset to the integer value. That way funny things
|
||||
// like this work properly: &(((struct foo *) 0xa)->f)
|
||||
return Base;
|
||||
|
||||
default:
|
||||
assert ("Unhandled Base.");
|
||||
return Base;
|
||||
}
|
||||
|
||||
return loc::MemRegionVal(MRMgr.getFieldRegion(D, BaseR));
|
||||
}
|
||||
|
||||
SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base,
|
||||
|
@ -108,7 +142,7 @@ SVal BasicStoreManager::GetSVal(Store St, Loc LV, QualType T) {
|
|||
switch (LV.getSubKind()) {
|
||||
|
||||
case loc::MemRegionKind: {
|
||||
VarRegion* R =
|
||||
const VarRegion* R =
|
||||
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
|
||||
|
||||
if (!R)
|
||||
|
@ -145,7 +179,7 @@ SVal BasicStoreManager::GetSVal(Store St, Loc LV, QualType T) {
|
|||
Store BasicStoreManager::SetSVal(Store store, Loc LV, SVal V) {
|
||||
switch (LV.getSubKind()) {
|
||||
case loc::MemRegionKind: {
|
||||
VarRegion* R =
|
||||
const VarRegion* R =
|
||||
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
|
||||
|
||||
if (!R)
|
||||
|
@ -165,8 +199,8 @@ Store BasicStoreManager::SetSVal(Store store, Loc LV, SVal V) {
|
|||
Store BasicStoreManager::Remove(Store store, Loc LV) {
|
||||
switch (LV.getSubKind()) {
|
||||
case loc::MemRegionKind: {
|
||||
VarRegion* R =
|
||||
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
|
||||
const VarRegion* R =
|
||||
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
|
||||
|
||||
if (!R)
|
||||
return store;
|
||||
|
|
|
@ -1513,7 +1513,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
|
|||
state = state.remove<RefBindings>(Sym);
|
||||
}
|
||||
|
||||
TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
|
||||
const TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
|
||||
if (R) {
|
||||
// Set the value of the variable to be a conjured symbol.
|
||||
unsigned Count = Builder.getCurrentBlockCount();
|
||||
|
@ -1717,7 +1717,7 @@ void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
|
|||
if (!isa<loc::MemRegionVal>(TargetLV))
|
||||
escapes = true;
|
||||
else {
|
||||
MemRegion* R = cast<loc::MemRegionVal>(TargetLV).getRegion();
|
||||
const MemRegion* R = cast<loc::MemRegionVal>(TargetLV).getRegion();
|
||||
escapes = !Eng.getStateManager().hasStackStorage(R);
|
||||
}
|
||||
|
||||
|
|
|
@ -216,7 +216,11 @@ void NSErrorCheck::CheckParamDeref(VarDecl* Param, GRStateRef rootState,
|
|||
GRExprEngine& Eng, GRBugReporter& BR,
|
||||
bool isNSErrorWarning) {
|
||||
|
||||
SVal ParamSVal = rootState.GetLValue(Param);
|
||||
SVal ParamL = rootState.GetLValue(Param);
|
||||
const MemRegion* ParamR = cast<loc::MemRegionVal>(ParamL).getRegionAs<VarRegion>();
|
||||
assert (ParamR && "Parameters always have VarRegions.");
|
||||
SVal ParamSVal = rootState.GetSVal(ParamR);
|
||||
|
||||
|
||||
// FIXME: For now assume that ParamSVal is symbolic. We need to generalize
|
||||
// this later.
|
||||
|
|
|
@ -56,6 +56,15 @@ void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
|||
DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
|
||||
}
|
||||
|
||||
void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
|
||||
ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
|
||||
ID.AddInteger(sym.getNumber());
|
||||
}
|
||||
|
||||
void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
SymbolicRegion::ProfileRegion(ID, sym);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Region pretty-printing.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -75,6 +84,10 @@ void VarRegion::print(llvm::raw_ostream& os) const {
|
|||
os << cast<VarDecl>(D)->getName();
|
||||
}
|
||||
|
||||
void SymbolicRegion::print(llvm::raw_ostream& os) const {
|
||||
os << "$" << sym.getNumber();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MemRegionManager methods.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -106,7 +119,7 @@ MemSpaceRegion* MemRegionManager::getUnknownRegion() {
|
|||
}
|
||||
|
||||
VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
|
||||
MemRegion* superRegion) {
|
||||
const MemRegion* superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
|
||||
|
||||
|
@ -123,8 +136,27 @@ VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
|
|||
return R;
|
||||
}
|
||||
|
||||
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
|
||||
SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
SymbolicRegion::ProfileRegion(ID, sym);
|
||||
|
||||
void* InsertPos;
|
||||
MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
|
||||
SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
|
||||
|
||||
if (!R) {
|
||||
R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
|
||||
new (R) SymbolicRegion(sym);
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
|
||||
MemRegion* superRegion) {
|
||||
const MemRegion* superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
|
||||
|
||||
|
@ -141,8 +173,9 @@ FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
|
|||
return R;
|
||||
}
|
||||
|
||||
ObjCIvarRegion* MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
|
||||
MemRegion* superRegion) {
|
||||
ObjCIvarRegion*
|
||||
MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
|
||||
const MemRegion* superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
|
||||
|
||||
|
@ -181,11 +214,20 @@ AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
|
|||
}
|
||||
|
||||
bool MemRegionManager::hasStackStorage(const MemRegion* R) {
|
||||
const SubRegion* SR = dyn_cast<SubRegion>(R);
|
||||
|
||||
// Only subregions can have stack storage.
|
||||
if (!SR)
|
||||
return false;
|
||||
|
||||
MemSpaceRegion* S = getStackRegion();
|
||||
|
||||
while (R) {
|
||||
if (R == S) return true;
|
||||
R = R->getSuperRegion();
|
||||
while (SR) {
|
||||
R = SR->getSuperRegion();
|
||||
if (R == S)
|
||||
return true;
|
||||
|
||||
SR = dyn_cast<SubRegion>(R);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
Store RegionStoreManager::SetSVal(Store store, Loc LV, SVal V) {
|
||||
assert(LV.getSubKind() == loc::MemRegionKind);
|
||||
|
||||
MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
|
||||
const MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
|
||||
|
||||
if (!R)
|
||||
return store;
|
||||
|
|
Загрузка…
Ссылка в новой задаче