forked from OSchip/llvm-project
Use SymbolicRegion instead of CodeTextRegion for symbolic function
pointers. Most logic cares first about whether or not a region is symbolic, and second if represents code. This should fix a series of silent corner case bugs (as well as simplify a bunch of code). llvm-svn: 80335
This commit is contained in:
parent
0e8901803c
commit
198a8c5f95
|
@ -240,32 +240,12 @@ public:
|
|||
/// 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 {
|
||||
public:
|
||||
enum CodeKind { Declared, Symbolic };
|
||||
|
||||
private:
|
||||
// The function pointer kind that this CodeTextRegion represents.
|
||||
CodeKind codekind;
|
||||
|
||||
// Data may be a SymbolRef or FunctionDecl*.
|
||||
const void* Data;
|
||||
|
||||
// Cached function pointer type.
|
||||
QualType LocationType;
|
||||
const FunctionDecl *FD;
|
||||
|
||||
public:
|
||||
|
||||
CodeTextRegion(const FunctionDecl* fd, QualType t, const MemRegion* sreg)
|
||||
: TypedRegion(sreg, CodeTextRegionKind),
|
||||
codekind(Declared),
|
||||
Data(fd),
|
||||
LocationType(t) {}
|
||||
|
||||
CodeTextRegion(SymbolRef sym, QualType t, const MemRegion* sreg)
|
||||
: TypedRegion(sreg, CodeTextRegionKind),
|
||||
codekind(Symbolic),
|
||||
Data(sym),
|
||||
LocationType(t) {}
|
||||
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.
|
||||
|
@ -274,30 +254,21 @@ public:
|
|||
}
|
||||
|
||||
QualType getLocationType(ASTContext &C) const {
|
||||
return LocationType;
|
||||
return C.getPointerType(FD->getType());
|
||||
}
|
||||
|
||||
bool isDeclared() const { return codekind == Declared; }
|
||||
bool isSymbolic() const { return codekind == Symbolic; }
|
||||
|
||||
const FunctionDecl* getDecl() const {
|
||||
assert(codekind == Declared);
|
||||
return static_cast<const FunctionDecl*>(Data);
|
||||
const FunctionDecl *getDecl() const {
|
||||
return FD;
|
||||
}
|
||||
|
||||
SymbolRef getSymbol() const {
|
||||
assert(codekind == Symbolic);
|
||||
return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data));
|
||||
}
|
||||
|
||||
|
||||
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 void* data, QualType t, const MemRegion*);
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
|
||||
const MemRegion*);
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() == CodeTextRegionKind;
|
||||
|
@ -680,11 +651,10 @@ public:
|
|||
/// a specified Objective-c instance variable. 'superRegion' corresponds
|
||||
/// to the containing region (which typically represents the Objective-C
|
||||
/// object).
|
||||
ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
|
||||
ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
|
||||
const MemRegion* superRegion);
|
||||
|
||||
CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t);
|
||||
CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t);
|
||||
CodeTextRegion *getCodeTextRegion(const FunctionDecl *FD);
|
||||
|
||||
template <typename RegionTy, typename A1>
|
||||
RegionTy* getRegion(const A1 a1);
|
||||
|
@ -832,7 +802,7 @@ template <> struct MemRegionManagerTrait<SymbolicRegion> {
|
|||
template<> struct MemRegionManagerTrait<CodeTextRegion> {
|
||||
typedef MemSpaceRegion SuperRegionTy;
|
||||
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
|
||||
const FunctionDecl*, QualType) {
|
||||
const FunctionDecl*) {
|
||||
return MRMgr.getCodeRegion();
|
||||
}
|
||||
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
|
||||
|
|
|
@ -126,15 +126,15 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
|||
ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
|
||||
}
|
||||
|
||||
void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
|
||||
QualType t, const MemRegion*) {
|
||||
void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
const FunctionDecl *FD,
|
||||
const MemRegion*) {
|
||||
ID.AddInteger(MemRegion::CodeTextRegionKind);
|
||||
ID.AddPointer(data);
|
||||
ID.Add(t);
|
||||
ID.AddPointer(FD);
|
||||
}
|
||||
|
||||
void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
CodeTextRegion::ProfileRegion(ID, Data, LocationType, superRegion);
|
||||
CodeTextRegion::ProfileRegion(ID, FD, superRegion);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -161,13 +161,7 @@ void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
|
|||
}
|
||||
|
||||
void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
os << "code{";
|
||||
if (isDeclared())
|
||||
os << getDecl()->getDeclName().getAsString();
|
||||
else
|
||||
os << '$' << getSymbol();
|
||||
|
||||
os << '}';
|
||||
os << "code{" << getDecl()->getDeclName().getAsString() << '}';
|
||||
}
|
||||
|
||||
void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
|
||||
|
@ -293,13 +287,8 @@ MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
|
|||
return R;
|
||||
}
|
||||
|
||||
CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
|
||||
QualType t) {
|
||||
return getRegion<CodeTextRegion>(fd, t);
|
||||
}
|
||||
|
||||
CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
|
||||
return getRegion<CodeTextRegion>(sym, t);
|
||||
CodeTextRegion *MemRegionManager::getCodeTextRegion(const FunctionDecl *FD) {
|
||||
return getRegion<CodeTextRegion>(FD);
|
||||
}
|
||||
|
||||
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
|
||||
|
|
|
@ -42,28 +42,20 @@ bool SVal::hasConjuredSymbol() const {
|
|||
SymbolRef sym = SR->getSymbol();
|
||||
if (isa<SymbolConjured>(sym))
|
||||
return true;
|
||||
} else if (const CodeTextRegion *CTR = dyn_cast<CodeTextRegion>(R)) {
|
||||
if (CTR->isSymbolic()) {
|
||||
SymbolRef sym = CTR->getSymbol();
|
||||
if (isa<SymbolConjured>(sym))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const FunctionDecl* SVal::getAsFunctionDecl() 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 (CTR->isDeclared())
|
||||
return CTR->getDecl();
|
||||
}
|
||||
if (const CodeTextRegion *CTR = R->getAs<CodeTextRegion>())
|
||||
return CTR->getDecl();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
|
||||
|
|
|
@ -52,16 +52,12 @@ StoreManager::CastRegion(const GRState *state, const MemRegion* R,
|
|||
return CastResult(state, R->getBaseRegion());
|
||||
|
||||
if (CastToTy->isBlockPointerType()) {
|
||||
if (isa<CodeTextRegion>(R))
|
||||
return CastResult(state, R);
|
||||
|
||||
// FIXME: This may not be the right approach, depending on the symbol
|
||||
// FIXME: We may need different solutions, depending on the symbol
|
||||
// involved. Blocks can be casted to/from 'id', as they can be treated
|
||||
// as Objective-C objects.
|
||||
if (SymbolRef sym = loc::MemRegionVal(R).getAsSymbol()) {
|
||||
R = MRMgr.getCodeTextRegion(sym, CastToTy);
|
||||
// as Objective-C objects. This could possibly be handled by enhancing
|
||||
// our reasoning of downcasts of symbolic objects.
|
||||
if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R))
|
||||
return CastResult(state, R);
|
||||
}
|
||||
|
||||
// We don't know what to make of it. Return a NULL region, which
|
||||
// will be interpretted as UnknownVal.
|
||||
|
|
|
@ -80,11 +80,6 @@ SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
|
|||
return UnknownVal();
|
||||
|
||||
SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
|
||||
|
||||
// If T is of function pointer type or a block pointer type, create a
|
||||
// CodeTextRegion wrapping that symbol.
|
||||
if (T->isFunctionPointerType() || T->isBlockPointerType())
|
||||
return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
@ -92,7 +87,7 @@ SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
|
|||
return nonloc::SymbolVal(sym);
|
||||
}
|
||||
|
||||
SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
|
||||
SVal ValueManager::getConjuredSymbolVal(const Expr *E, unsigned Count) {
|
||||
QualType T = E->getType();
|
||||
|
||||
if (!SymbolManager::canSymbolicate(T))
|
||||
|
@ -100,18 +95,13 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
|
|||
|
||||
SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);
|
||||
|
||||
// If T is of function pointer type or a block pointer type, create a
|
||||
// CodeTextRegion wrapping a symbol.
|
||||
if (T->isFunctionPointerType() || T->isBlockPointerType())
|
||||
return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
||||
return nonloc::SymbolVal(sym);
|
||||
}
|
||||
|
||||
SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
|
||||
SVal ValueManager::getConjuredSymbolVal(const Expr *E, QualType T,
|
||||
unsigned Count) {
|
||||
|
||||
if (!SymbolManager::canSymbolicate(T))
|
||||
|
@ -119,11 +109,6 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
|
|||
|
||||
SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count);
|
||||
|
||||
// If T is of function pointer type or a block pointer type, create a
|
||||
// CodeTextRegion wrapping a symbol.
|
||||
if (T->isFunctionPointerType() || T->isBlockPointerType())
|
||||
return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
||||
|
@ -147,7 +132,6 @@ SVal ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
|
|||
}
|
||||
|
||||
SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
|
||||
CodeTextRegion* R
|
||||
= MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType()));
|
||||
CodeTextRegion *R = MemMgr.getCodeTextRegion(FD);
|
||||
return loc::MemRegionVal(R);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue