[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:
Artem Dergachev 2017-04-13 09:56:07 +00:00
parent d4998b0344
commit 6dd11048f5
8 changed files with 123 additions and 92 deletions

View File

@ -458,8 +458,8 @@ 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)
: SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
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,
@ -906,8 +914,15 @@ class VarRegion : public DeclRegion {
friend class MemRegionManager;
// Constructors and private methods.
VarRegion(const VarDecl *vd, const MemRegion* sReg)
: DeclRegion(vd, sReg, VarRegionKind) {}
VarRegion(const VarDecl *vd, const MemRegion *sReg)
: 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,9 +1069,9 @@ class ElementRegion : public TypedValueRegion {
QualType ElementType;
NonLoc Index;
ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
: TypedValueRegion(sReg, ElementRegionKind),
ElementType(elementType), Index(Idx) {
ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
: TypedValueRegion(sReg, ElementRegionKind),
ElementType(elementType), Index(Idx) {
assert((!Idx.getAs<nonloc::ConcreteInt>() ||
Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
"The index must be signed");
@ -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);
}
@ -1254,16 +1272,16 @@ public:
/// getVarRegion - Retrieve or create the memory region associated with
/// a specified VarDecl and super region.
const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
/// 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,17 +1344,22 @@ 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 SuperTy,
typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
const Arg3Ty arg3,
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 REG>
const REG* LazyAllocate(REG*& region);

View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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,8 +182,8 @@ DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
svalBuilder.getArrayIndexType());
}
ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
: DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
: DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
return cast<ObjCIvarDecl>(D);
@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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));
}