forked from OSchip/llvm-project
[analyzer] Enforce super-region classes for various memory regions.
We now check the type of the super-region pointer for most SubRegion classes in compile time; some checks are run-time though. This is an API-breaking change (we now require explicit casts to specific region sub-classes), but in practice very few checkers are affected. Differential Revision: https://reviews.llvm.org/D26838 llvm-svn: 300189
This commit is contained in:
parent
d4998b0344
commit
6dd11048f5
|
@ -458,7 +458,7 @@ class AllocaRegion : public SubRegion {
|
|||
// memory allocated by alloca at the same call site.
|
||||
const Expr *Ex;
|
||||
|
||||
AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
|
||||
AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
|
||||
: SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
|
||||
assert(Ex);
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ class CodeTextRegion : public TypedRegion {
|
|||
virtual void anchor() override;
|
||||
|
||||
protected:
|
||||
CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {
|
||||
CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
|
||||
assert(classof(this));
|
||||
}
|
||||
|
||||
|
@ -565,7 +565,7 @@ class FunctionCodeRegion : public CodeTextRegion {
|
|||
|
||||
const NamedDecl *FD;
|
||||
|
||||
FunctionCodeRegion(const NamedDecl *fd, const MemRegion* sreg)
|
||||
FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
|
||||
: CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
|
||||
assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
|
||||
}
|
||||
|
@ -616,7 +616,7 @@ class BlockCodeRegion : public CodeTextRegion {
|
|||
CanQualType locTy;
|
||||
|
||||
BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
|
||||
AnalysisDeclContext *ac, const MemRegion* sreg)
|
||||
AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
|
||||
: CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
|
||||
assert(bd);
|
||||
assert(ac);
|
||||
|
@ -663,11 +663,14 @@ class BlockDataRegion : public TypedRegion {
|
|||
void *OriginalVars;
|
||||
|
||||
BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
|
||||
unsigned count, const MemRegion *sreg)
|
||||
unsigned count, const MemSpaceRegion *sreg)
|
||||
: TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
|
||||
BlockCount(count), ReferencedVars(nullptr), OriginalVars(nullptr) {
|
||||
assert(bc);
|
||||
assert(lc);
|
||||
assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
|
||||
isa<StackLocalsSpaceRegion>(sreg) ||
|
||||
isa<UnknownSpaceRegion>(sreg));
|
||||
}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
|
||||
|
@ -741,12 +744,13 @@ class SymbolicRegion : public SubRegion {
|
|||
|
||||
const SymbolRef sym;
|
||||
|
||||
SymbolicRegion(const SymbolRef s, const MemRegion *sreg)
|
||||
SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
|
||||
: SubRegion(sreg, SymbolicRegionKind), sym(s) {
|
||||
assert(s);
|
||||
assert(s->getType()->isAnyPointerType() ||
|
||||
s->getType()->isReferenceType() ||
|
||||
s->getType()->isBlockPointerType());
|
||||
assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -777,7 +781,7 @@ class StringRegion : public TypedValueRegion {
|
|||
|
||||
const StringLiteral* Str;
|
||||
|
||||
StringRegion(const StringLiteral *str, const MemRegion *sreg)
|
||||
StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
|
||||
: TypedValueRegion(sreg, StringRegionKind), Str(str) {
|
||||
assert(str);
|
||||
}
|
||||
|
@ -815,7 +819,8 @@ class ObjCStringRegion : public TypedValueRegion {
|
|||
|
||||
const ObjCStringLiteral* Str;
|
||||
|
||||
ObjCStringRegion(const ObjCStringLiteral *str, const MemRegion *sreg)
|
||||
ObjCStringRegion(const ObjCStringLiteral *str,
|
||||
const GlobalInternalSpaceRegion *sreg)
|
||||
: TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
|
||||
assert(str);
|
||||
}
|
||||
|
@ -853,9 +858,12 @@ class CompoundLiteralRegion : public TypedValueRegion {
|
|||
|
||||
const CompoundLiteralExpr *CL;
|
||||
|
||||
CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion *sReg)
|
||||
CompoundLiteralRegion(const CompoundLiteralExpr *cl,
|
||||
const MemSpaceRegion *sReg)
|
||||
: TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
|
||||
assert(cl);
|
||||
assert(isa<GlobalInternalSpaceRegion>(sReg) ||
|
||||
isa<StackLocalsSpaceRegion>(sReg));
|
||||
}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
|
@ -907,7 +915,14 @@ class VarRegion : public DeclRegion {
|
|||
|
||||
// Constructors and private methods.
|
||||
VarRegion(const VarDecl *vd, const MemRegion *sReg)
|
||||
: DeclRegion(vd, sReg, VarRegionKind) {}
|
||||
: DeclRegion(vd, sReg, VarRegionKind) {
|
||||
// VarRegion appears in unknown space when it's a block variable as seen
|
||||
// from a block using it, when this block is analyzed at top-level.
|
||||
// Other block variables appear within block data regions,
|
||||
// which, unlike everything else on this list, are not memory spaces.
|
||||
assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
|
||||
isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
|
||||
}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
|
||||
const MemRegion *superRegion) {
|
||||
|
@ -943,7 +958,8 @@ public:
|
|||
class CXXThisRegion : public TypedValueRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
CXXThisRegion(const PointerType *thisPointerTy, const MemRegion *sReg)
|
||||
CXXThisRegion(const PointerType *thisPointerTy,
|
||||
const StackArgumentsSpaceRegion *sReg)
|
||||
: TypedValueRegion(sReg, CXXThisRegionKind),
|
||||
ThisPointerTy(thisPointerTy) {}
|
||||
|
||||
|
@ -971,7 +987,7 @@ private:
|
|||
class FieldRegion : public DeclRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
|
||||
FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
|
||||
: DeclRegion(fd, sReg, FieldRegionKind) {}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
|
||||
|
@ -1004,7 +1020,7 @@ public:
|
|||
class ObjCIvarRegion : public DeclRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
|
||||
ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
|
||||
const MemRegion* superRegion);
|
||||
|
@ -1053,7 +1069,7 @@ class ElementRegion : public TypedValueRegion {
|
|||
QualType ElementType;
|
||||
NonLoc Index;
|
||||
|
||||
ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
|
||||
ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
|
||||
: TypedValueRegion(sReg, ElementRegionKind),
|
||||
ElementType(elementType), Index(Idx) {
|
||||
assert((!Idx.getAs<nonloc::ConcreteInt>() ||
|
||||
|
@ -1093,9 +1109,11 @@ class CXXTempObjectRegion : public TypedValueRegion {
|
|||
|
||||
Expr const *Ex;
|
||||
|
||||
CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
|
||||
CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
|
||||
: TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
|
||||
assert(E);
|
||||
assert(isa<StackLocalsSpaceRegion>(sReg) ||
|
||||
isa<GlobalInternalSpaceRegion>(sReg));
|
||||
}
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID &ID,
|
||||
|
@ -1125,7 +1143,7 @@ class CXXBaseObjectRegion : public TypedValueRegion {
|
|||
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
|
||||
|
||||
CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
|
||||
const MemRegion *SReg)
|
||||
const SubRegion *SReg)
|
||||
: TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
|
||||
assert(RD);
|
||||
}
|
||||
|
@ -1259,11 +1277,11 @@ public:
|
|||
/// getElementRegion - Retrieve the memory region associated with the
|
||||
/// associated element type, index, and super region.
|
||||
const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
|
||||
const MemRegion *superRegion,
|
||||
const SubRegion *superRegion,
|
||||
ASTContext &Ctx);
|
||||
|
||||
const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
|
||||
const MemRegion *superRegion) {
|
||||
const SubRegion *superRegion) {
|
||||
return getElementRegion(ER->getElementType(), ER->getIndex(),
|
||||
superRegion, ER->getContext());
|
||||
}
|
||||
|
@ -1273,10 +1291,10 @@ public:
|
|||
/// memory region (which typically represents the memory representing
|
||||
/// a structure or class).
|
||||
const FieldRegion *getFieldRegion(const FieldDecl *fd,
|
||||
const MemRegion* superRegion);
|
||||
const SubRegion* superRegion);
|
||||
|
||||
const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
|
||||
const MemRegion *superRegion) {
|
||||
const SubRegion *superRegion) {
|
||||
return getFieldRegion(FR->getDecl(), superRegion);
|
||||
}
|
||||
|
||||
|
@ -1285,7 +1303,7 @@ public:
|
|||
/// to the containing region (which typically represents the Objective-C
|
||||
/// object).
|
||||
const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
|
||||
const MemRegion* superRegion);
|
||||
const SubRegion* superRegion);
|
||||
|
||||
const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
|
||||
LocationContext const *LC);
|
||||
|
@ -1295,14 +1313,14 @@ public:
|
|||
///
|
||||
/// The type of \p Super is assumed be a class deriving from \p BaseClass.
|
||||
const CXXBaseObjectRegion *
|
||||
getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
|
||||
getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
|
||||
bool IsVirtual);
|
||||
|
||||
/// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
|
||||
/// super region.
|
||||
const CXXBaseObjectRegion *
|
||||
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
|
||||
const MemRegion *superRegion) {
|
||||
const SubRegion *superRegion) {
|
||||
return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
|
||||
baseReg->isVirtual());
|
||||
}
|
||||
|
@ -1326,16 +1344,21 @@ public:
|
|||
const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
|
||||
|
||||
private:
|
||||
template <typename RegionTy, typename A1>
|
||||
RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
|
||||
template <typename RegionTy, typename SuperTy,
|
||||
typename Arg1Ty>
|
||||
RegionTy* getSubRegion(const Arg1Ty arg1,
|
||||
const SuperTy* superRegion);
|
||||
|
||||
template <typename RegionTy, typename A1, typename A2>
|
||||
RegionTy* getSubRegion(const A1 a1, const A2 a2,
|
||||
const MemRegion* superRegion);
|
||||
template <typename RegionTy, typename SuperTy,
|
||||
typename Arg1Ty, typename Arg2Ty>
|
||||
RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
|
||||
const SuperTy* superRegion);
|
||||
|
||||
template <typename RegionTy, typename A1, typename A2, typename A3>
|
||||
RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
|
||||
const MemRegion* superRegion);
|
||||
template <typename RegionTy, typename SuperTy,
|
||||
typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
|
||||
RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
|
||||
const Arg3Ty arg3,
|
||||
const SuperTy* superRegion);
|
||||
|
||||
template <typename REG>
|
||||
const REG* LazyAllocate(REG*& region);
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
/// valid only if Failed flag is set to false.
|
||||
SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
|
||||
|
||||
const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
|
||||
const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
|
||||
|
||||
/// castRegion - Used by ExprEngine::VisitCast to handle casts from
|
||||
/// a MemRegion* to a specific location type. 'R' is the region being
|
||||
|
@ -259,8 +259,9 @@ public:
|
|||
virtual void iterBindings(Store store, BindingsHandler& f) = 0;
|
||||
|
||||
protected:
|
||||
const MemRegion *MakeElementRegion(const MemRegion *baseRegion,
|
||||
QualType pointeeTy, uint64_t index = 0);
|
||||
const ElementRegion *MakeElementRegion(const SubRegion *baseRegion,
|
||||
QualType pointeeTy,
|
||||
uint64_t index = 0);
|
||||
|
||||
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
|
||||
/// implicit casts that arise from loads from regions that are reinterpreted
|
||||
|
|
|
@ -153,9 +153,9 @@ void MPIChecker::allRegionsUsedByWait(
|
|||
MemRegionManager *const RegionManager = MR->getMemRegionManager();
|
||||
|
||||
if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
|
||||
const MemRegion *SuperRegion{nullptr};
|
||||
const SubRegion *SuperRegion{nullptr};
|
||||
if (const ElementRegion *const ER = MR->getAs<ElementRegion>()) {
|
||||
SuperRegion = ER->getSuperRegion();
|
||||
SuperRegion = cast<SubRegion>(ER->getSuperRegion());
|
||||
}
|
||||
|
||||
// A single request is passed to MPI_Waitall.
|
||||
|
|
|
@ -512,7 +512,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
if (CNE->isArray()) {
|
||||
// FIXME: allocating an array requires simulating the constructors.
|
||||
// For now, just return a symbolicated region.
|
||||
const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
|
||||
const SubRegion *NewReg =
|
||||
symVal.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
|
||||
QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
|
||||
const ElementRegion *EleReg =
|
||||
getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
|
||||
|
|
|
@ -31,54 +31,56 @@ using namespace ento;
|
|||
// MemRegion Construction.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <typename RegionTy, typename A1>
|
||||
RegionTy* MemRegionManager::getSubRegion(const A1 a1,
|
||||
const MemRegion *superRegion) {
|
||||
template <typename RegionTy, typename SuperTy, typename Arg1Ty>
|
||||
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
|
||||
const SuperTy *superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
RegionTy::ProfileRegion(ID, a1, superRegion);
|
||||
RegionTy::ProfileRegion(ID, arg1, superRegion);
|
||||
void *InsertPos;
|
||||
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
|
||||
InsertPos));
|
||||
|
||||
if (!R) {
|
||||
R = A.Allocate<RegionTy>();
|
||||
new (R) RegionTy(a1, superRegion);
|
||||
new (R) RegionTy(arg1, superRegion);
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
template <typename RegionTy, typename A1, typename A2>
|
||||
RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
|
||||
const MemRegion *superRegion) {
|
||||
template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
|
||||
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
|
||||
const SuperTy *superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
RegionTy::ProfileRegion(ID, a1, a2, superRegion);
|
||||
RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
|
||||
void *InsertPos;
|
||||
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
|
||||
InsertPos));
|
||||
|
||||
if (!R) {
|
||||
R = A.Allocate<RegionTy>();
|
||||
new (R) RegionTy(a1, a2, superRegion);
|
||||
new (R) RegionTy(arg1, arg2, superRegion);
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
template <typename RegionTy, typename A1, typename A2, typename A3>
|
||||
RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
|
||||
const MemRegion *superRegion) {
|
||||
template <typename RegionTy, typename SuperTy,
|
||||
typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
|
||||
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
|
||||
const Arg3Ty arg3,
|
||||
const SuperTy *superRegion) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
|
||||
RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
|
||||
void *InsertPos;
|
||||
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
|
||||
InsertPos));
|
||||
|
||||
if (!R) {
|
||||
R = A.Allocate<RegionTy>();
|
||||
new (R) RegionTy(a1, a2, a3, superRegion);
|
||||
new (R) RegionTy(arg1, arg2, arg3, superRegion);
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
|
@ -180,7 +182,7 @@ DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
|
|||
svalBuilder.getArrayIndexType());
|
||||
}
|
||||
|
||||
ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
|
||||
ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
|
||||
: DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
|
||||
|
||||
const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
|
||||
|
@ -735,12 +737,14 @@ const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
|
|||
// Constructing regions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
|
||||
return getSubRegion<StringRegion>(Str, getGlobalsRegion());
|
||||
return getSubRegion<StringRegion>(
|
||||
Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
|
||||
}
|
||||
|
||||
const ObjCStringRegion *
|
||||
MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
|
||||
return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
|
||||
return getSubRegion<ObjCStringRegion>(
|
||||
Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
|
||||
}
|
||||
|
||||
/// Look through a chain of LocationContexts to either find the
|
||||
|
@ -869,7 +873,7 @@ const BlockDataRegion *
|
|||
MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
|
||||
const LocationContext *LC,
|
||||
unsigned blockCount) {
|
||||
const MemRegion *sReg = nullptr;
|
||||
const MemSpaceRegion *sReg = nullptr;
|
||||
const BlockDecl *BD = BC->getDecl();
|
||||
if (!BD->hasCaptures()) {
|
||||
// This handles 'static' blocks.
|
||||
|
@ -902,7 +906,7 @@ MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
|
|||
const CompoundLiteralRegion*
|
||||
MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
|
||||
const LocationContext *LC) {
|
||||
const MemRegion *sReg = nullptr;
|
||||
const MemSpaceRegion *sReg = nullptr;
|
||||
|
||||
if (CL->isFileScope())
|
||||
sReg = getGlobalsRegion();
|
||||
|
@ -917,7 +921,7 @@ MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
|
|||
|
||||
const ElementRegion*
|
||||
MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
|
||||
const MemRegion* superRegion,
|
||||
const SubRegion* superRegion,
|
||||
ASTContext &Ctx){
|
||||
QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
|
||||
|
||||
|
@ -960,13 +964,13 @@ const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
|
|||
|
||||
const FieldRegion*
|
||||
MemRegionManager::getFieldRegion(const FieldDecl *d,
|
||||
const MemRegion* superRegion){
|
||||
const SubRegion* superRegion){
|
||||
return getSubRegion<FieldRegion>(d, superRegion);
|
||||
}
|
||||
|
||||
const ObjCIvarRegion*
|
||||
MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
|
||||
const MemRegion* superRegion) {
|
||||
const SubRegion* superRegion) {
|
||||
return getSubRegion<ObjCIvarRegion>(d, superRegion);
|
||||
}
|
||||
|
||||
|
@ -1002,7 +1006,7 @@ static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
|
|||
|
||||
const CXXBaseObjectRegion *
|
||||
MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
|
||||
const MemRegion *Super,
|
||||
const SubRegion *Super,
|
||||
bool IsVirtual) {
|
||||
if (isa<TypedValueRegion>(Super)) {
|
||||
assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
|
||||
|
@ -1013,7 +1017,7 @@ MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
|
|||
// are different.
|
||||
while (const CXXBaseObjectRegion *Base =
|
||||
dyn_cast<CXXBaseObjectRegion>(Super)) {
|
||||
Super = Base->getSuperRegion();
|
||||
Super = cast<SubRegion>(Base->getSuperRegion());
|
||||
}
|
||||
assert(Super && !isa<MemSpaceRegion>(Super));
|
||||
}
|
||||
|
|
|
@ -1341,7 +1341,8 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array, QualType T) {
|
|||
if (!Array.getAs<loc::MemRegionVal>())
|
||||
return UnknownVal();
|
||||
|
||||
const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
|
||||
const SubRegion *R =
|
||||
cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion());
|
||||
NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
|
||||
return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
|
||||
}
|
||||
|
@ -1384,7 +1385,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
|
|||
T = SR->getSymbol()->getType();
|
||||
}
|
||||
}
|
||||
MR = GetElementZeroRegion(MR, T);
|
||||
MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
|
||||
}
|
||||
|
||||
// FIXME: Perhaps this method should just take a 'const MemRegion*' argument
|
||||
|
|
|
@ -950,7 +950,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
|
|||
if (const MemRegion *region = lhs.getAsRegion()) {
|
||||
rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
|
||||
SVal index = UnknownVal();
|
||||
const MemRegion *superR = nullptr;
|
||||
const SubRegion *superR = nullptr;
|
||||
// We need to know the type of the pointer in order to add an integer to it.
|
||||
// Depending on the type, different amount of bytes is added.
|
||||
QualType elementType;
|
||||
|
@ -959,13 +959,13 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
|
|||
assert(op == BO_Add || op == BO_Sub);
|
||||
index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
|
||||
getArrayIndexType());
|
||||
superR = elemReg->getSuperRegion();
|
||||
superR = cast<SubRegion>(elemReg->getSuperRegion());
|
||||
elementType = elemReg->getElementType();
|
||||
}
|
||||
else if (isa<SubRegion>(region)) {
|
||||
assert(op == BO_Add || op == BO_Sub);
|
||||
index = (op == BO_Add) ? rhs : evalMinus(rhs);
|
||||
superR = region;
|
||||
superR = cast<SubRegion>(region);
|
||||
// TODO: Is this actually reliable? Maybe improving our MemRegion
|
||||
// hierarchy to provide typed regions for all non-void pointers would be
|
||||
// better. For instance, we cannot extend this towards LocAsInteger
|
||||
|
|
|
@ -42,8 +42,9 @@ StoreRef StoreManager::enterStackFrame(Store OldStore,
|
|||
return Store;
|
||||
}
|
||||
|
||||
const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base,
|
||||
QualType EleTy, uint64_t index) {
|
||||
const ElementRegion *StoreManager::MakeElementRegion(const SubRegion *Base,
|
||||
QualType EleTy,
|
||||
uint64_t index) {
|
||||
NonLoc idx = svalBuilder.makeArrayIndex(index);
|
||||
return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext());
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) {
|
|||
return StoreRef(store, *this);
|
||||
}
|
||||
|
||||
const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
|
||||
const ElementRegion *StoreManager::GetElementZeroRegion(const SubRegion *R,
|
||||
QualType T) {
|
||||
NonLoc idx = svalBuilder.makeZeroArrayIndex();
|
||||
assert(!T.isNull());
|
||||
|
@ -126,7 +127,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
|
|||
case MemRegion::VarRegionKind:
|
||||
case MemRegion::CXXTempObjectRegionKind:
|
||||
case MemRegion::CXXBaseObjectRegionKind:
|
||||
return MakeElementRegion(R, PointeeTy);
|
||||
return MakeElementRegion(cast<SubRegion>(R), PointeeTy);
|
||||
|
||||
case MemRegion::ElementRegionKind: {
|
||||
// If we are casting from an ElementRegion to another type, the
|
||||
|
@ -171,7 +172,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
|
|||
}
|
||||
|
||||
// Otherwise, create a new ElementRegion at offset 0.
|
||||
return MakeElementRegion(baseR, PointeeTy);
|
||||
return MakeElementRegion(cast<SubRegion>(baseR), PointeeTy);
|
||||
}
|
||||
|
||||
// We have a non-zero offset from the base region. We want to determine
|
||||
|
@ -202,10 +203,11 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
|
|||
if (!newSuperR) {
|
||||
// Create an intermediate ElementRegion to represent the raw byte.
|
||||
// This will be the super region of the final ElementRegion.
|
||||
newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity());
|
||||
newSuperR = MakeElementRegion(cast<SubRegion>(baseR), Ctx.CharTy,
|
||||
off.getQuantity());
|
||||
}
|
||||
|
||||
return MakeElementRegion(newSuperR, PointeeTy, newIndex);
|
||||
return MakeElementRegion(cast<SubRegion>(newSuperR), PointeeTy, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,9 +273,8 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
|
|||
BaseDecl = BaseType->getAsCXXRecordDecl();
|
||||
assert(BaseDecl && "not a C++ object?");
|
||||
|
||||
const MemRegion *BaseReg =
|
||||
MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(),
|
||||
IsVirtual);
|
||||
const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
|
||||
BaseDecl, cast<SubRegion>(DerivedRegVal->getRegion()), IsVirtual);
|
||||
|
||||
return loc::MemRegionVal(BaseReg);
|
||||
}
|
||||
|
@ -390,11 +391,11 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
|
|||
return Base;
|
||||
|
||||
Loc BaseL = Base.castAs<Loc>();
|
||||
const MemRegion* BaseR = nullptr;
|
||||
const SubRegion* BaseR = nullptr;
|
||||
|
||||
switch (BaseL.getSubKind()) {
|
||||
case loc::MemRegionValKind:
|
||||
BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
|
||||
BaseR = cast<SubRegion>(BaseL.castAs<loc::MemRegionVal>().getRegion());
|
||||
break;
|
||||
|
||||
case loc::GotoLabelKind:
|
||||
|
@ -434,7 +435,8 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
|
|||
if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
|
||||
return Base;
|
||||
|
||||
const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
|
||||
const SubRegion *BaseRegion =
|
||||
Base.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
|
||||
|
||||
// Pointer of any type can be cast and used as array base.
|
||||
const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
|
||||
|
@ -471,9 +473,8 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
|
|||
if (isa<ElementRegion>(BaseRegion->StripCasts()))
|
||||
return UnknownVal();
|
||||
|
||||
return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
|
||||
ElemR->getSuperRegion(),
|
||||
Ctx));
|
||||
return loc::MemRegionVal(MRMgr.getElementRegion(
|
||||
elementType, Offset, cast<SubRegion>(ElemR->getSuperRegion()), Ctx));
|
||||
}
|
||||
|
||||
const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
|
||||
|
@ -484,7 +485,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
|
|||
OffI));
|
||||
|
||||
// Construct the new ElementRegion.
|
||||
const MemRegion *ArrayR = ElemR->getSuperRegion();
|
||||
const SubRegion *ArrayR = cast<SubRegion>(ElemR->getSuperRegion());
|
||||
return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
|
||||
Ctx));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue