forked from OSchip/llvm-project
Split CodeTextRegion into FunctionTextRegion and BlockTextRegion. This a precursor to having basic static analysis support for blocks.
llvm-svn: 89828
This commit is contained in:
parent
906d871e6c
commit
10a50e7371
|
@ -48,7 +48,8 @@ public:
|
|||
AllocaRegionKind,
|
||||
// Typed regions.
|
||||
BEG_TYPED_REGIONS,
|
||||
CodeTextRegionKind,
|
||||
FunctionTextRegionKind,
|
||||
BlockTextRegionKind,
|
||||
CompoundLiteralRegionKind,
|
||||
StringRegionKind, ElementRegionKind,
|
||||
// Decl Regions.
|
||||
|
@ -237,43 +238,78 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// CodeTextRegion - A region that represents code texts of a function. It wraps
|
||||
/// two kinds of code texts: real function and symbolic function. Real function
|
||||
/// is a function declared in the program. Symbolic function is a function
|
||||
/// pointer that we don't know which function it points to.
|
||||
|
||||
class CodeTextRegion : public TypedRegion {
|
||||
const FunctionDecl *FD;
|
||||
|
||||
protected:
|
||||
CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
|
||||
public:
|
||||
|
||||
CodeTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
|
||||
: TypedRegion(sreg, CodeTextRegionKind), FD(fd) {}
|
||||
|
||||
QualType getValueType(ASTContext &C) const {
|
||||
// Do not get the object type of a CodeTextRegion.
|
||||
assert(0);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
bool isBoundable() const { return false; }
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
Kind k = R->getKind();
|
||||
return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// FunctionTextRegion - A region that represents code texts of function.
|
||||
class FunctionTextRegion : public CodeTextRegion {
|
||||
const FunctionDecl *FD;
|
||||
public:
|
||||
FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
|
||||
: CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
|
||||
|
||||
QualType getLocationType(ASTContext &C) const {
|
||||
return C.getPointerType(FD->getType());
|
||||
}
|
||||
|
||||
|
||||
const FunctionDecl *getDecl() const {
|
||||
return FD;
|
||||
}
|
||||
|
||||
bool isBoundable() const { return false; }
|
||||
|
||||
|
||||
virtual void dumpToStream(llvm::raw_ostream& os) const;
|
||||
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const;
|
||||
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
|
||||
const MemRegion*);
|
||||
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() == CodeTextRegionKind;
|
||||
return R->getKind() == FunctionTextRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// BlockTextRegion - A region that represents code texts of blocks (closures).
|
||||
class BlockTextRegion : public CodeTextRegion {
|
||||
const BlockDecl *BD;
|
||||
CanQualType locTy;
|
||||
public:
|
||||
BlockTextRegion(const BlockDecl *bd, CanQualType lTy, const MemRegion* sreg)
|
||||
: CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), locTy(lTy) {}
|
||||
|
||||
QualType getLocationType(ASTContext &C) const {
|
||||
return locTy;
|
||||
}
|
||||
|
||||
const BlockDecl *getDecl() const {
|
||||
return BD;
|
||||
}
|
||||
|
||||
virtual void dumpToStream(llvm::raw_ostream& os) const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const;
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
|
||||
CanQualType, const MemRegion*);
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() == BlockTextRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -656,7 +692,9 @@ public:
|
|||
ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
|
||||
const MemRegion* superRegion);
|
||||
|
||||
CodeTextRegion *getCodeTextRegion(const FunctionDecl *FD);
|
||||
FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
|
||||
BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy);
|
||||
|
||||
|
||||
template <typename RegionTy, typename A1>
|
||||
RegionTy* getRegion(const A1 a1);
|
||||
|
@ -801,18 +839,21 @@ template <> struct MemRegionManagerTrait<SymbolicRegion> {
|
|||
}
|
||||
};
|
||||
|
||||
template<> struct MemRegionManagerTrait<CodeTextRegion> {
|
||||
template<> struct MemRegionManagerTrait<FunctionTextRegion> {
|
||||
typedef MemSpaceRegion SuperRegionTy;
|
||||
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
|
||||
const FunctionDecl*) {
|
||||
return MRMgr.getCodeRegion();
|
||||
}
|
||||
};
|
||||
template<> struct MemRegionManagerTrait<BlockTextRegion> {
|
||||
typedef MemSpaceRegion SuperRegionTy;
|
||||
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
|
||||
SymbolRef, QualType) {
|
||||
const BlockDecl*, CanQualType) {
|
||||
return MRMgr.getCodeRegion();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -114,6 +114,8 @@ public:
|
|||
const TypedRegion *R);
|
||||
|
||||
DefinedSVal getFunctionPointer(const FunctionDecl *FD);
|
||||
|
||||
DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy);
|
||||
|
||||
NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
|
||||
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
|
||||
|
|
|
@ -126,15 +126,26 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
|||
ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
|
||||
}
|
||||
|
||||
void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
const FunctionDecl *FD,
|
||||
const MemRegion*) {
|
||||
ID.AddInteger(MemRegion::CodeTextRegionKind);
|
||||
void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
const FunctionDecl *FD,
|
||||
const MemRegion*) {
|
||||
ID.AddInteger(MemRegion::FunctionTextRegionKind);
|
||||
ID.AddPointer(FD);
|
||||
}
|
||||
|
||||
void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
CodeTextRegion::ProfileRegion(ID, FD, superRegion);
|
||||
void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
|
||||
}
|
||||
|
||||
void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
const BlockDecl *BD, CanQualType,
|
||||
const MemRegion*) {
|
||||
ID.AddInteger(MemRegion::BlockTextRegionKind);
|
||||
ID.AddPointer(BD);
|
||||
}
|
||||
|
||||
void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -160,10 +171,14 @@ void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
|
|||
os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
|
||||
}
|
||||
|
||||
void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
os << "code{" << getDecl()->getDeclName().getAsString() << '}';
|
||||
}
|
||||
|
||||
void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
os << "block{" << (void*) this << '}';
|
||||
}
|
||||
|
||||
void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
// FIXME: More elaborate pretty-printing.
|
||||
os << "{ " << (void*) CL << " }";
|
||||
|
@ -287,10 +302,17 @@ MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
|
|||
return R;
|
||||
}
|
||||
|
||||
CodeTextRegion *MemRegionManager::getCodeTextRegion(const FunctionDecl *FD) {
|
||||
return getRegion<CodeTextRegion>(FD);
|
||||
FunctionTextRegion *
|
||||
MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
|
||||
return getRegion<FunctionTextRegion>(FD);
|
||||
}
|
||||
|
||||
BlockTextRegion *MemRegionManager::getBlockTextRegion(const BlockDecl *BD,
|
||||
CanQualType locTy) {
|
||||
return getRegion<BlockTextRegion>(BD, locTy);
|
||||
}
|
||||
|
||||
|
||||
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
|
||||
SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
|
||||
return getRegion<SymbolicRegion>(sym);
|
||||
|
|
|
@ -59,8 +59,8 @@ void PthreadLockChecker::PostVisitCallExpr(CheckerContext &C,
|
|||
const CallExpr *CE) {
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
const CodeTextRegion *R =
|
||||
dyn_cast_or_null<CodeTextRegion>(state->getSVal(Callee).getAsRegion());
|
||||
const FunctionTextRegion *R =
|
||||
dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
|
||||
|
||||
if (!R)
|
||||
return;
|
||||
|
|
|
@ -712,7 +712,8 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
|
|||
assert(0 && "Cannot index into a MemSpace");
|
||||
return UnknownVal();
|
||||
|
||||
case MemRegion::CodeTextRegionKind:
|
||||
case MemRegion::FunctionTextRegionKind:
|
||||
case MemRegion::BlockTextRegionKind:
|
||||
// Technically this can happen if people do funny things with casts.
|
||||
return UnknownVal();
|
||||
|
||||
|
@ -857,7 +858,8 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state,
|
|||
case MemRegion::ObjCIvarRegionKind:
|
||||
return UnknownVal();
|
||||
|
||||
case MemRegion::CodeTextRegionKind:
|
||||
case MemRegion::FunctionTextRegionKind:
|
||||
case MemRegion::BlockTextRegionKind:
|
||||
// Technically this can happen if people do funny things with casts.
|
||||
return UnknownVal();
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ bool SVal::hasConjuredSymbol() const {
|
|||
const FunctionDecl *SVal::getAsFunctionDecl() const {
|
||||
if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
|
||||
const MemRegion* R = X->getRegion();
|
||||
if (const CodeTextRegion *CTR = R->getAs<CodeTextRegion>())
|
||||
if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
|
||||
return CTR->getDecl();
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy)
|
|||
assert(0 && "Invalid region cast");
|
||||
break;
|
||||
}
|
||||
case MemRegion::CodeTextRegionKind: {
|
||||
|
||||
case MemRegion::FunctionTextRegionKind:
|
||||
case MemRegion::BlockTextRegionKind: {
|
||||
// CodeTextRegion should be cast to only a function or block pointer type,
|
||||
// although they can in practice be casted to anything, e.g, void*, char*,
|
||||
// etc.
|
||||
|
|
|
@ -138,6 +138,13 @@ ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
|
|||
}
|
||||
|
||||
DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
|
||||
CodeTextRegion *R = MemMgr.getCodeTextRegion(FD);
|
||||
CodeTextRegion *R = MemMgr.getFunctionTextRegion(FD);
|
||||
return loc::MemRegionVal(R);
|
||||
}
|
||||
|
||||
DefinedSVal ValueManager::getBlockPointer(const BlockDecl *BD,
|
||||
CanQualType locTy) {
|
||||
CodeTextRegion *R = MemMgr.getBlockTextRegion(BD, locTy);
|
||||
return loc::MemRegionVal(R);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue