[analyzer] Introduce new MemRegion, "TypedValueRegion", so that we can separate TypedRegions that implement getValueType() from those that don't.

Patch by Olaf Krzikalla!

llvm-svn: 137498
This commit is contained in:
Ted Kremenek 2011-08-12 20:02:48 +00:00
parent 30e697ebaf
commit 8df44b2632
17 changed files with 117 additions and 100 deletions

View File

@ -49,17 +49,17 @@ public:
class LazyCompoundValData : public llvm::FoldingSetNode { class LazyCompoundValData : public llvm::FoldingSetNode {
StoreRef store; StoreRef store;
const TypedRegion *region; const TypedValueRegion *region;
public: public:
LazyCompoundValData(const StoreRef &st, const TypedRegion *r) LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
: store(st), region(r) {} : store(st), region(r) {}
const void *getStore() const { return store.getStore(); } const void *getStore() const { return store.getStore(); }
const TypedRegion *getRegion() const { return region; } const TypedValueRegion *getRegion() const { return region; }
static void Profile(llvm::FoldingSetNodeID& ID, static void Profile(llvm::FoldingSetNodeID& ID,
const StoreRef &store, const StoreRef &store,
const TypedRegion *region); const TypedValueRegion *region);
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
}; };
@ -176,7 +176,7 @@ public:
llvm::ImmutableList<SVal> Vals); llvm::ImmutableList<SVal> Vals);
const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
const TypedRegion *region); const TypedValueRegion *region);
llvm::ImmutableList<SVal> getEmptySValList() { llvm::ImmutableList<SVal> getEmptySValList() {
return SValListFactory.getEmptyList(); return SValListFactory.getEmptyList();

View File

@ -82,12 +82,13 @@ public:
// Untyped regions. // Untyped regions.
SymbolicRegionKind, SymbolicRegionKind,
AllocaRegionKind, AllocaRegionKind,
BlockDataRegionKind,
// Typed regions. // Typed regions.
BEG_TYPED_REGIONS, BEG_TYPED_REGIONS,
FunctionTextRegionKind = BEG_TYPED_REGIONS, FunctionTextRegionKind = BEG_TYPED_REGIONS,
BlockTextRegionKind, BlockTextRegionKind,
BlockDataRegionKind, BEG_TYPED_VALUE_REGIONS,
CompoundLiteralRegionKind, CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
CXXThisRegionKind, CXXThisRegionKind,
StringRegionKind, StringRegionKind,
ElementRegionKind, ElementRegionKind,
@ -99,7 +100,8 @@ public:
END_DECL_REGIONS = ObjCIvarRegionKind, END_DECL_REGIONS = ObjCIvarRegionKind,
CXXTempObjectRegionKind, CXXTempObjectRegionKind,
CXXBaseObjectRegionKind, CXXBaseObjectRegionKind,
END_TYPED_REGIONS = CXXBaseObjectRegionKind END_TYPED_REGIONS = CXXBaseObjectRegionKind,
END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind
}; };
private: private:
@ -352,6 +354,26 @@ class TypedRegion : public SubRegion {
protected: protected:
TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
public:
virtual QualType getLocationType() const = 0;
QualType getDesugaredLocationType(ASTContext &Context) const {
return getLocationType().getDesugaredType(Context);
}
bool isBoundable() const { return true; }
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
}
};
/// TypedValueRegion - An abstract class representing regions having a typed value.
class TypedValueRegion : public TypedRegion {
protected:
TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
public: public:
virtual QualType getValueType() const = 0; virtual QualType getValueType() const = 0;
@ -369,15 +391,9 @@ public:
return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
} }
QualType getDesugaredLocationType(ASTContext &Context) const {
return getLocationType().getDesugaredType(Context);
}
bool isBoundable() const { return true; }
static bool classof(const MemRegion* R) { static bool classof(const MemRegion* R) {
unsigned k = R->getKind(); unsigned k = R->getKind();
return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
} }
}; };
@ -386,11 +402,6 @@ class CodeTextRegion : public TypedRegion {
protected: protected:
CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
public: public:
QualType getValueType() const {
assert(0 && "Do not get the object type of a CodeTextRegion.");
return QualType();
}
bool isBoundable() const { return false; } bool isBoundable() const { return false; }
static bool classof(const MemRegion* R) { static bool classof(const MemRegion* R) {
@ -566,13 +577,13 @@ public:
}; };
/// StringRegion - Region associated with a StringLiteral. /// StringRegion - Region associated with a StringLiteral.
class StringRegion : public TypedRegion { class StringRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;
const StringLiteral* Str; const StringLiteral* Str;
protected: protected:
StringRegion(const StringLiteral* str, const MemRegion* sreg) StringRegion(const StringLiteral* str, const MemRegion* sreg)
: TypedRegion(sreg, StringRegionKind), Str(str) {} : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, static void ProfileRegion(llvm::FoldingSetNodeID& ID,
const StringLiteral* Str, const StringLiteral* Str,
@ -604,13 +615,13 @@ public:
/// CompoundLiteralRegion - A memory region representing a compound literal. /// CompoundLiteralRegion - A memory region representing a compound literal.
/// Compound literals are essentially temporaries that are stack allocated /// Compound literals are essentially temporaries that are stack allocated
/// or in the global constant pool. /// or in the global constant pool.
class CompoundLiteralRegion : public TypedRegion { class CompoundLiteralRegion : public TypedValueRegion {
private: private:
friend class MemRegionManager; friend class MemRegionManager;
const CompoundLiteralExpr* CL; const CompoundLiteralExpr* CL;
CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg) CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
: TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, static void ProfileRegion(llvm::FoldingSetNodeID& ID,
const CompoundLiteralExpr* CL, const CompoundLiteralExpr* CL,
@ -633,12 +644,12 @@ public:
} }
}; };
class DeclRegion : public TypedRegion { class DeclRegion : public TypedValueRegion {
protected: protected:
const Decl* D; const Decl* D;
DeclRegion(const Decl* d, const MemRegion* sReg, Kind k) DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
: TypedRegion(sReg, k), D(d) {} : TypedValueRegion(sReg, k), D(d) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
const MemRegion* superRegion, Kind k); const MemRegion* superRegion, Kind k);
@ -689,11 +700,11 @@ public:
/// CXXThisRegion - Represents the region for the implicit 'this' parameter /// CXXThisRegion - Represents the region for the implicit 'this' parameter
/// in a call to a C++ method. This region doesn't represent the object /// in a call to a C++ method. This region doesn't represent the object
/// referred to by 'this', but rather 'this' itself. /// referred to by 'this', but rather 'this' itself.
class CXXThisRegion : public TypedRegion { class CXXThisRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;
CXXThisRegion(const PointerType *thisPointerTy, CXXThisRegion(const PointerType *thisPointerTy,
const MemRegion *sReg) const MemRegion *sReg)
: TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
static void ProfileRegion(llvm::FoldingSetNodeID &ID, static void ProfileRegion(llvm::FoldingSetNodeID &ID,
const PointerType *PT, const PointerType *PT,
@ -792,14 +803,14 @@ public:
void dump() const; void dump() const;
}; };
class ElementRegion : public TypedRegion { class ElementRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;
QualType ElementType; QualType ElementType;
NonLoc Index; NonLoc Index;
ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
: TypedRegion(sReg, ElementRegionKind), : TypedValueRegion(sReg, ElementRegionKind),
ElementType(elementType), Index(Idx) { ElementType(elementType), Index(Idx) {
assert((!isa<nonloc::ConcreteInt>(&Idx) || assert((!isa<nonloc::ConcreteInt>(&Idx) ||
cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
@ -833,13 +844,13 @@ public:
}; };
// C++ temporary object associated with an expression. // C++ temporary object associated with an expression.
class CXXTempObjectRegion : public TypedRegion { class CXXTempObjectRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;
Expr const *Ex; Expr const *Ex;
CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
: TypedRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
static void ProfileRegion(llvm::FoldingSetNodeID &ID, static void ProfileRegion(llvm::FoldingSetNodeID &ID,
Expr const *E, const MemRegion *sReg); Expr const *E, const MemRegion *sReg);
@ -860,13 +871,13 @@ public:
// CXXBaseObjectRegion represents a base object within a C++ object. It is // CXXBaseObjectRegion represents a base object within a C++ object. It is
// identified by the base class declaration and the region of its parent object. // identified by the base class declaration and the region of its parent object.
class CXXBaseObjectRegion : public TypedRegion { class CXXBaseObjectRegion : public TypedValueRegion {
friend class MemRegionManager; friend class MemRegionManager;
const CXXRecordDecl *decl; const CXXRecordDecl *decl;
CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg) CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
: TypedRegion(sReg, CXXBaseObjectRegionKind), decl(d) {} : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
static void ProfileRegion(llvm::FoldingSetNodeID &ID, static void ProfileRegion(llvm::FoldingSetNodeID &ID,
const CXXRecordDecl *decl, const MemRegion *sReg); const CXXRecordDecl *decl, const MemRegion *sReg);

View File

@ -130,7 +130,7 @@ public:
DefinedOrUnknownSVal makeZeroVal(QualType type); DefinedOrUnknownSVal makeZeroVal(QualType type);
/// getRegionValueSymbolVal - make a unique symbol for value of region. /// getRegionValueSymbolVal - make a unique symbol for value of region.
DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *region); DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region);
DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
const Expr *expr, unsigned count); const Expr *expr, unsigned count);
@ -139,7 +139,7 @@ public:
unsigned count); unsigned count);
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal( DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
SymbolRef parentSymbol, const TypedRegion *region); SymbolRef parentSymbol, const TypedValueRegion *region);
DefinedSVal getMetadataSymbolVal( DefinedSVal getMetadataSymbolVal(
const void *symbolTag, const MemRegion *region, const void *symbolTag, const MemRegion *region,
@ -154,7 +154,8 @@ public:
return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals)); return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
} }
NonLoc makeLazyCompoundVal(const StoreRef &store, const TypedRegion *region) { NonLoc makeLazyCompoundVal(const StoreRef &store,
const TypedValueRegion *region) {
return nonloc::LazyCompoundVal( return nonloc::LazyCompoundVal(
BasicVals.getLazyCompoundValData(store, region)); BasicVals.getLazyCompoundValData(store, region));
} }

View File

@ -219,8 +219,8 @@ protected:
/// CastRetrievedVal - Used by subclasses of StoreManager to implement /// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted /// implicit casts that arise from loads from regions that are reinterpreted
/// as another region. /// as another region.
SVal CastRetrievedVal(SVal val, const TypedRegion *region, QualType castTy, SVal CastRetrievedVal(SVal val, const TypedValueRegion *region,
bool performTestOnly = true); QualType castTy, bool performTestOnly = true);
private: private:
SVal getLValueFieldOrIvar(const Decl* decl, SVal base); SVal getLValueFieldOrIvar(const Decl* decl, SVal base);

View File

@ -37,7 +37,7 @@ namespace ento {
class BasicValueFactory; class BasicValueFactory;
class MemRegion; class MemRegion;
class SubRegion; class SubRegion;
class TypedRegion; class TypedValueRegion;
class VarRegion; class VarRegion;
class SymExpr : public llvm::FoldingSetNode { class SymExpr : public llvm::FoldingSetNode {
@ -95,15 +95,15 @@ typedef llvm::SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
/// A symbol representing the value of a MemRegion. /// A symbol representing the value of a MemRegion.
class SymbolRegionValue : public SymbolData { class SymbolRegionValue : public SymbolData {
const TypedRegion *R; const TypedValueRegion *R;
public: public:
SymbolRegionValue(SymbolID sym, const TypedRegion *r) SymbolRegionValue(SymbolID sym, const TypedValueRegion *r)
: SymbolData(RegionValueKind, sym), R(r) {} : SymbolData(RegionValueKind, sym), R(r) {}
const TypedRegion* getRegion() const { return R; } const TypedValueRegion* getRegion() const { return R; }
static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) { static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) {
profile.AddInteger((unsigned) RegionValueKind); profile.AddInteger((unsigned) RegionValueKind);
profile.AddPointer(R); profile.AddPointer(R);
} }
@ -166,21 +166,21 @@ public:
/// symbolic value. /// symbolic value.
class SymbolDerived : public SymbolData { class SymbolDerived : public SymbolData {
SymbolRef parentSymbol; SymbolRef parentSymbol;
const TypedRegion *R; const TypedValueRegion *R;
public: public:
SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r) SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r)
: SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
SymbolRef getParentSymbol() const { return parentSymbol; } SymbolRef getParentSymbol() const { return parentSymbol; }
const TypedRegion *getRegion() const { return R; } const TypedValueRegion *getRegion() const { return R; }
QualType getType(ASTContext&) const; QualType getType(ASTContext&) const;
void dumpToStream(raw_ostream &os) const; void dumpToStream(raw_ostream &os) const;
static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
const TypedRegion *r) { const TypedValueRegion *r) {
profile.AddInteger((unsigned) DerivedKind); profile.AddInteger((unsigned) DerivedKind);
profile.AddPointer(r); profile.AddPointer(r);
profile.AddPointer(parent); profile.AddPointer(parent);
@ -380,7 +380,7 @@ public:
static bool canSymbolicate(QualType T); static bool canSymbolicate(QualType T);
/// \brief Make a unique symbol for MemRegion R according to its kind. /// \brief Make a unique symbol for MemRegion R according to its kind.
const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R); const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R);
const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
unsigned VisitCount, unsigned VisitCount,
@ -392,7 +392,7 @@ public:
} }
const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
const TypedRegion *R); const TypedValueRegion *R);
const SymbolExtent *getExtentSymbol(const SubRegion *R); const SymbolExtent *getExtentSymbol(const SubRegion *R);

View File

@ -290,7 +290,7 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
if (!LV) if (!LV)
return; return;
const TypedRegion* R = dyn_cast<TypedRegion>(LV->stripCasts()); const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
if (!R) if (!R)
return; return;

View File

@ -770,8 +770,7 @@ const GRState *CStringChecker::InvalidateBuffer(CheckerContext &C,
bool CStringChecker::SummarizeRegion(raw_ostream& os, ASTContext& Ctx, bool CStringChecker::SummarizeRegion(raw_ostream& os, ASTContext& Ctx,
const MemRegion *MR) { const MemRegion *MR) {
const TypedRegion *TR = dyn_cast<TypedRegion>(MR); const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
if (!TR) const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
return false;
switch (TR->getKind()) { switch (TR->getKind()) {
case MemRegion::FunctionTextRegionKind: { case MemRegion::FunctionTextRegionKind: {
@ -790,16 +789,16 @@ bool CStringChecker::SummarizeRegion(raw_ostream& os, ASTContext& Ctx,
return true; return true;
case MemRegion::CXXThisRegionKind: case MemRegion::CXXThisRegionKind:
case MemRegion::CXXTempObjectRegionKind: case MemRegion::CXXTempObjectRegionKind:
os << "a C++ temp object of type " << TR->getValueType().getAsString(); os << "a C++ temp object of type " << TVR->getValueType().getAsString();
return true; return true;
case MemRegion::VarRegionKind: case MemRegion::VarRegionKind:
os << "a variable of type" << TR->getValueType().getAsString(); os << "a variable of type" << TVR->getValueType().getAsString();
return true; return true;
case MemRegion::FieldRegionKind: case MemRegion::FieldRegionKind:
os << "a field of type " << TR->getValueType().getAsString(); os << "a field of type " << TVR->getValueType().getAsString();
return true; return true;
case MemRegion::ObjCIvarRegionKind: case MemRegion::ObjCIvarRegionKind:
os << "an instance variable of type " << TR->getValueType().getAsString(); os << "an instance variable of type " << TVR->getValueType().getAsString();
return true; return true;
default: default:
return false; return false;

View File

@ -116,7 +116,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
MemRegionManager &mrMgr, Store s) MemRegionManager &mrMgr, Store s)
: C(c), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {} : C(c), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
bool Find(const TypedRegion *R) { bool Find(const TypedValueRegion *R) {
QualType T = R->getValueType(); QualType T = R->getValueType();
if (const RecordType *RT = T->getAsStructureType()) { if (const RecordType *RT = T->getAsStructureType()) {
const RecordDecl *RD = RT->getDecl()->getDefinition(); const RecordDecl *RD = RT->getDecl()->getDefinition();

View File

@ -106,8 +106,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C,
// LoadTy specifying can be omitted. But we put it here to emphasize the // LoadTy specifying can be omitted. But we put it here to emphasize the
// semantics. // semantics.
QualType LoadTy; QualType LoadTy;
if (const TypedRegion *TR = if (const TypedValueRegion *TR =
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) { dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
LoadTy = TR->getValueType(); LoadTy = TR->getValueType();
} }
Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(), Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(),
@ -159,8 +159,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C,
SVal val = stateEqual->getSVal(newValueExpr); SVal val = stateEqual->getSVal(newValueExpr);
// Handle implicit value casts. // Handle implicit value casts.
if (const TypedRegion *R = if (const TypedValueRegion *R =
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) { dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
val = svalBuilder.evalCast(val,R->getValueType(), newValueExpr->getType()); val = svalBuilder.evalCast(val,R->getValueType(), newValueExpr->getType());
} }

View File

@ -27,7 +27,7 @@ void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID, void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
const StoreRef &store, const StoreRef &store,
const TypedRegion *region) { const TypedValueRegion *region) {
ID.AddPointer(store.getStore()); ID.AddPointer(store.getStore());
ID.AddPointer(region); ID.AddPointer(region);
} }
@ -128,7 +128,7 @@ BasicValueFactory::getCompoundValData(QualType T,
const LazyCompoundValData* const LazyCompoundValData*
BasicValueFactory::getLazyCompoundValData(const StoreRef &store, BasicValueFactory::getLazyCompoundValData(const StoreRef &store,
const TypedRegion *region) { const TypedValueRegion *region) {
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
LazyCompoundValData::Profile(ID, store, region); LazyCompoundValData::Profile(ID, store, region);
void* InsertPos; void* InsertPos;

View File

@ -140,7 +140,7 @@ public:
if (isa<loc::ConcreteInt>(V)) { if (isa<loc::ConcreteInt>(V)) {
bool b = false; bool b = false;
if (R->isBoundable()) { if (R->isBoundable()) {
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
if (TR->getValueType()->isObjCObjectPointerType()) { if (TR->getValueType()->isObjCObjectPointerType()) {
os << "initialized to nil"; os << "initialized to nil";
b = true; b = true;
@ -170,7 +170,7 @@ public:
if (isa<loc::ConcreteInt>(V)) { if (isa<loc::ConcreteInt>(V)) {
bool b = false; bool b = false;
if (R->isBoundable()) { if (R->isBoundable()) {
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
if (TR->getValueType()->isObjCObjectPointerType()) { if (TR->getValueType()->isObjCObjectPointerType()) {
os << "nil object reference stored to "; os << "nil object reference stored to ";
b = true; b = true;

View File

@ -1522,8 +1522,8 @@ void ExprEngine::evalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
// Are we loading from a region? This actually results in two loads; one // Are we loading from a region? This actually results in two loads; one
// to fetch the address of the referenced value and one to fetch the // to fetch the address of the referenced value and one to fetch the
// referenced value. // referenced value.
if (const TypedRegion *TR = if (const TypedValueRegion *TR =
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) { dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
QualType ValTy = TR->getValueType(); QualType ValTy = TR->getValueType();
if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
@ -1894,7 +1894,8 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
const GRState *noElems = state->BindExpr(S, FalseV); const GRState *noElems = state->BindExpr(S, FalseV);
if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV)) if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
if (const TypedRegion *R = dyn_cast<TypedRegion>(MV->getRegion())) { if (const TypedValueRegion *R =
dyn_cast<TypedValueRegion>(MV->getRegion())) {
// FIXME: The proper thing to do is to really iterate over the // FIXME: The proper thing to do is to really iterate over the
// container. We will do this with dispatch logic to the store. // container. We will do this with dispatch logic to the store.
// For now, just 'conjure' up a symbolic value. // For now, just 'conjure' up a symbolic value.

View File

@ -200,7 +200,7 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
if (!R->isBoundable()) if (!R->isBoundable())
return UnknownVal(); return UnknownVal();
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
QualType T = TR->getValueType(); QualType T = TR->getValueType();
if (Loc::isLocType(T) || T->isIntegerType()) if (Loc::isLocType(T) || T->isIntegerType())
return getSVal(R); return getSVal(R);

View File

@ -288,9 +288,9 @@ public: // Part of public interface to class.
} }
/// BindStruct - Bind a compound value to a structure. /// BindStruct - Bind a compound value to a structure.
StoreRef BindStruct(Store store, const TypedRegion* R, SVal V); StoreRef BindStruct(Store store, const TypedValueRegion* R, SVal V);
StoreRef BindArray(Store store, const TypedRegion* R, SVal V); StoreRef BindArray(Store store, const TypedValueRegion* R, SVal V);
/// KillStruct - Set the entire struct to unknown. /// KillStruct - Set the entire struct to unknown.
StoreRef KillStruct(Store store, const TypedRegion* R, SVal DefaultVal); StoreRef KillStruct(Store store, const TypedRegion* R, SVal DefaultVal);
@ -335,9 +335,9 @@ public: // Part of public interface to class.
SVal RetrieveVar(Store store, const VarRegion *R); SVal RetrieveVar(Store store, const VarRegion *R);
SVal RetrieveLazySymbol(const TypedRegion *R); SVal RetrieveLazySymbol(const TypedValueRegion *R);
SVal RetrieveFieldOrElementCommon(Store store, const TypedRegion *R, SVal RetrieveFieldOrElementCommon(Store store, const TypedValueRegion *R,
QualType Ty, const MemRegion *superR); QualType Ty, const MemRegion *superR);
SVal RetrieveLazyBinding(const MemRegion *lazyBindingRegion, SVal RetrieveLazyBinding(const MemRegion *lazyBindingRegion,
@ -348,15 +348,16 @@ public: // Part of public interface to class.
/// 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 TypedRegion* R); SVal RetrieveStruct(Store store, const TypedValueRegion* R);
SVal RetrieveArray(Store store, const TypedRegion* R); SVal RetrieveArray(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> RetrieveDerivedDefaultValue(RegionBindings B,
const MemRegion *superR, const MemRegion *superR,
const TypedRegion *R, QualType Ty); const TypedValueRegion *R,
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*>
@ -683,7 +684,7 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
if (!baseR->isBoundable()) if (!baseR->isBoundable())
return; return;
const TypedRegion *TR = cast<TypedRegion>(baseR); const TypedValueRegion *TR = cast<TypedValueRegion>(baseR);
QualType T = TR->getValueType(); QualType T = TR->getValueType();
// Invalidate the binding. // Invalidate the binding.
@ -805,7 +806,7 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
return UnknownVal(); return UnknownVal();
const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion(); const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R); const TypedValueRegion* ArrayR = dyn_cast<TypedValueRegion>(R);
if (!ArrayR) if (!ArrayR)
return UnknownVal(); return UnknownVal();
@ -854,7 +855,7 @@ Optional<SVal> RegionStoreManager::getDirectBinding(RegionBindings B,
Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B, Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
const MemRegion *R) { const MemRegion *R) {
if (R->isBoundable()) if (R->isBoundable())
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R))
if (TR->getValueType()->isUnionType()) if (TR->getValueType()->isUnionType())
return UnknownVal(); return UnknownVal();
@ -898,7 +899,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// FIXME: Perhaps this method should just take a 'const MemRegion*' argument // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
// instead of 'Loc', and have the other Loc cases handled at a higher level. // instead of 'Loc', and have the other Loc cases handled at a higher level.
const TypedRegion *R = cast<TypedRegion>(MR); const TypedValueRegion *R = cast<TypedValueRegion>(MR);
QualType RTy = R->getValueType(); QualType RTy = R->getValueType();
// FIXME: We should eventually handle funny addressing. e.g.: // FIXME: We should eventually handle funny addressing. e.g.:
@ -1074,7 +1075,8 @@ SVal RegionStoreManager::RetrieveElement(Store store,
if (!O.getRegion()) if (!O.getRegion())
return UnknownVal(); return UnknownVal();
if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) { if (const TypedValueRegion *baseR =
dyn_cast_or_null<TypedValueRegion>(O.getRegion())) {
QualType baseT = baseR->getValueType(); QualType baseT = baseR->getValueType();
if (baseT->isScalarType()) { if (baseT->isScalarType()) {
QualType elemT = R->getElementType(); QualType elemT = R->getElementType();
@ -1112,7 +1114,7 @@ SVal RegionStoreManager::RetrieveField(Store store,
Optional<SVal> Optional<SVal>
RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B, RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B,
const MemRegion *superR, const MemRegion *superR,
const TypedRegion *R, const TypedValueRegion *R,
QualType Ty) { QualType Ty) {
if (const Optional<SVal> &D = getDefaultBinding(B, superR)) { if (const Optional<SVal> &D = getDefaultBinding(B, superR)) {
@ -1146,7 +1148,7 @@ SVal RegionStoreManager::RetrieveLazyBinding(const MemRegion *lazyBindingRegion,
} }
SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store, SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
const TypedRegion *R, const TypedValueRegion *R,
QualType Ty, QualType Ty,
const MemRegion *superR) { const MemRegion *superR) {
@ -1181,7 +1183,8 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
// Currently we don't reason specially about Clang-style vectors. Check // Currently we don't reason specially about Clang-style vectors. Check
// if superR is a vector and if so return Unknown. // if superR is a vector and if so return Unknown.
if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) { if (const TypedValueRegion *typedSuperR =
dyn_cast<TypedValueRegion>(superR)) {
if (typedSuperR->getValueType()->isVectorType()) if (typedSuperR->getValueType()->isVectorType())
return UnknownVal(); return UnknownVal();
} }
@ -1270,18 +1273,20 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
return UndefinedVal(); return UndefinedVal();
} }
SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) { SVal RegionStoreManager::RetrieveLazySymbol(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, const TypedRegion* R) { SVal RegionStoreManager::RetrieveStruct(Store store,
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, const TypedRegion * R) { SVal RegionStoreManager::RetrieveArray(Store store,
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);
} }
@ -1325,14 +1330,14 @@ StoreRef RegionStoreManager::Bind(Store store, Loc L, SVal V) {
const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion(); const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
// Check if the region is a struct region. // Check if the region is a struct region.
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R))
if (TR->getValueType()->isStructureOrClassType()) if (TR->getValueType()->isStructureOrClassType())
return BindStruct(store, TR, V); return BindStruct(store, TR, V);
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
if (ER->getIndex().isZeroConstant()) { if (ER->getIndex().isZeroConstant()) {
if (const TypedRegion *superR = if (const TypedValueRegion *superR =
dyn_cast<TypedRegion>(ER->getSuperRegion())) { dyn_cast<TypedValueRegion>(ER->getSuperRegion())) {
QualType superTy = superR->getValueType(); QualType superTy = superR->getValueType();
// For now, just invalidate the fields of the struct/union/class. // For now, just invalidate the fields of the struct/union/class.
// This is for test rdar_test_7185607 in misc-ps-region-store.m. // This is for test rdar_test_7185607 in misc-ps-region-store.m.
@ -1412,7 +1417,7 @@ StoreRef RegionStoreManager::setImplicitDefaultValue(Store store,
V).getRootWithoutRetain(), *this); V).getRootWithoutRetain(), *this);
} }
StoreRef RegionStoreManager::BindArray(Store store, const TypedRegion* R, StoreRef RegionStoreManager::BindArray(Store store, const TypedValueRegion* R,
SVal Init) { SVal Init) {
const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType())); const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
@ -1471,7 +1476,7 @@ StoreRef RegionStoreManager::BindArray(Store store, const TypedRegion* R,
return newStore; return newStore;
} }
StoreRef RegionStoreManager::BindStruct(Store store, const TypedRegion* R, StoreRef RegionStoreManager::BindStruct(Store store, const TypedValueRegion* R,
SVal V) { SVal V) {
if (!Features.supportsFields()) if (!Features.supportsFields())

View File

@ -70,7 +70,7 @@ SVal SValBuilder::convertToArrayIndex(SVal val) {
} }
DefinedOrUnknownSVal DefinedOrUnknownSVal
SValBuilder::getRegionValueSymbolVal(const TypedRegion* region) { SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
QualType T = region->getValueType(); QualType T = region->getValueType();
if (!SymbolManager::canSymbolicate(T)) if (!SymbolManager::canSymbolicate(T))
@ -133,7 +133,7 @@ DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
DefinedOrUnknownSVal DefinedOrUnknownSVal
SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
const TypedRegion *region) { const TypedValueRegion *region) {
QualType T = region->getValueType(); QualType T = region->getValueType();
if (!SymbolManager::canSymbolicate(T)) if (!SymbolManager::canSymbolicate(T))

View File

@ -87,7 +87,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
// Handle casts from compatible types. // Handle casts from compatible types.
if (R->isBoundable()) if (R->isBoundable())
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
if (CanonPointeeTy == ObjTy) if (CanonPointeeTy == ObjTy)
return R; return R;
@ -157,7 +157,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
// Edge case: we are at 0 bytes off the beginning of baseR. We // Edge case: we are at 0 bytes off the beginning of baseR. We
// check to see if type we are casting to is the same as the base // check to see if type we are casting to is the same as the base
// region. If so, just return the base region. // region. If so, just return the base region.
if (const TypedRegion *TR = dyn_cast<TypedRegion>(baseR)) { if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(baseR)) {
QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
if (CanonPointeeTy == ObjTy) if (CanonPointeeTy == ObjTy)
@ -211,7 +211,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
/// CastRetrievedVal - Used by subclasses of StoreManager to implement /// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted /// implicit casts that arise from loads from regions that are reinterpreted
/// as another region. /// as another region.
SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R, SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
QualType castTy, bool performTestOnly) { QualType castTy, bool performTestOnly) {
if (castTy.isNull()) if (castTy.isNull())

View File

@ -90,7 +90,7 @@ void SymbolRegionValue::dumpToStream(raw_ostream& os) const {
} }
const SymbolRegionValue* const SymbolRegionValue*
SymbolManager::getRegionValueSymbol(const TypedRegion* R) { SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
llvm::FoldingSetNodeID profile; llvm::FoldingSetNodeID profile;
SymbolRegionValue::Profile(profile, R); SymbolRegionValue::Profile(profile, R);
void* InsertPos; void* InsertPos;
@ -125,7 +125,7 @@ SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, unsigned Count,
const SymbolDerived* const SymbolDerived*
SymbolManager::getDerivedSymbol(SymbolRef parentSymbol, SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
const TypedRegion *R) { const TypedValueRegion *R) {
llvm::FoldingSetNodeID profile; llvm::FoldingSetNodeID profile;
SymbolDerived::Profile(profile, parentSymbol, R); SymbolDerived::Profile(profile, parentSymbol, R);