зеркало из https://github.com/microsoft/clang-1.git
Add prototype for CodeTextRegion.
A CodeTextRegion wraps two kinds of data: FunctionDecl* or SymbolRef. The latter comes from the symbolic function pointer that are generated from function calls or input data. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68777 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
cf665e1fba
Коммит
ec13d92066
|
@ -39,6 +39,7 @@ class MemRegionManager;
|
|||
class MemRegion : public llvm::FoldingSetNode {
|
||||
public:
|
||||
enum Kind { MemSpaceRegionKind,
|
||||
CodeTextRegionKind,
|
||||
SymbolicRegionKind,
|
||||
AllocaRegionKind,
|
||||
// Typed regions.
|
||||
|
@ -113,7 +114,7 @@ public:
|
|||
return R->getKind() > MemSpaceRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// AllocaRegion - A region that represents an untyped blob of bytes created
|
||||
/// by a call to 'alloca'.
|
||||
class AllocaRegion : public SubRegion {
|
||||
|
@ -174,6 +175,58 @@ 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 {
|
||||
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;
|
||||
|
||||
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) {}
|
||||
|
||||
QualType getRValueType(ASTContext &C) const {
|
||||
// Do not get the object type of a CodeTextRegion.
|
||||
assert(0);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
QualType getLValueType(ASTContext &C) const {
|
||||
return LocationType;
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) const;
|
||||
|
||||
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
|
||||
const void* data, QualType t);
|
||||
|
||||
static bool classof(const MemRegion* R) {
|
||||
return R->getKind() == CodeTextRegionKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
|
||||
/// clases, SymbolicRegion represents a region that serves as an alias for
|
||||
/// either a real region, a NULL pointer, etc. It essentially is used to
|
||||
|
@ -492,6 +545,7 @@ class MemRegionManager {
|
|||
MemSpaceRegion* stack;
|
||||
MemSpaceRegion* heap;
|
||||
MemSpaceRegion* unknown;
|
||||
MemSpaceRegion* code;
|
||||
|
||||
public:
|
||||
MemRegionManager(llvm::BumpPtrAllocator& a)
|
||||
|
@ -515,6 +569,8 @@ public:
|
|||
/// memory space.
|
||||
MemSpaceRegion* getUnknownRegion();
|
||||
|
||||
MemSpaceRegion* getCodeRegion();
|
||||
|
||||
bool isGlobalsRegion(const MemRegion* R) {
|
||||
assert(R);
|
||||
return R == globals;
|
||||
|
@ -567,6 +623,9 @@ public:
|
|||
TypedViewRegion* getTypedViewRegion(QualType LValueType,
|
||||
const MemRegion* superRegion);
|
||||
|
||||
CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t);
|
||||
CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t);
|
||||
|
||||
bool hasStackStorage(const MemRegion* R);
|
||||
|
||||
private:
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
|
||||
SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
|
||||
SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);
|
||||
|
||||
SVal getFunctionPointer(const FunctionDecl* FD);
|
||||
};
|
||||
} // end clang namespace
|
||||
#endif
|
||||
|
|
|
@ -107,6 +107,17 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
|||
ElementRegion::ProfileRegion(ID, Index, superRegion);
|
||||
}
|
||||
|
||||
void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
|
||||
QualType t) {
|
||||
ID.AddInteger(MemRegion::CodeTextRegionKind);
|
||||
ID.AddPointer(data);
|
||||
ID.Add(t);
|
||||
}
|
||||
|
||||
void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||
CodeTextRegion::ProfileRegion(ID, Data, LocationType);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// getLValueType() and getRValueType()
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -209,6 +220,10 @@ MemSpaceRegion* MemRegionManager::getUnknownRegion() {
|
|||
return LazyAllocate(unknown);
|
||||
}
|
||||
|
||||
MemSpaceRegion* MemRegionManager::getCodeRegion() {
|
||||
return LazyAllocate(code);
|
||||
}
|
||||
|
||||
bool MemRegionManager::onStack(const MemRegion* R) {
|
||||
while (const SubRegion* SR = dyn_cast<SubRegion>(R))
|
||||
R = SR->getSuperRegion();
|
||||
|
@ -306,6 +321,39 @@ MemRegionManager::getElementRegion(SVal Idx, const TypedRegion* superRegion){
|
|||
return R;
|
||||
}
|
||||
|
||||
CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
|
||||
QualType t) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
CodeTextRegion::ProfileRegion(ID, fd, t);
|
||||
void* InsertPos;
|
||||
MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
|
||||
CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
|
||||
|
||||
if (!R) {
|
||||
R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
|
||||
new (R) CodeTextRegion(fd, t, getCodeRegion());
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
CodeTextRegion::ProfileRegion(ID, sym, t);
|
||||
void* InsertPos;
|
||||
MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
|
||||
CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
|
||||
|
||||
if (!R) {
|
||||
R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
|
||||
new (R) CodeTextRegion(sym, t, getCodeRegion());
|
||||
Regions.InsertNode(R, InsertPos);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
|
||||
SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
|
|
|
@ -282,6 +282,12 @@ SVal ValueManager::getRValueSymbolVal(const MemRegion* R) {
|
|||
|
||||
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
|
||||
QualType T = TR->getRValueType(SymMgr.getContext());
|
||||
|
||||
// If T is of function pointer type, create a CodeTextRegion wrapping a
|
||||
// symbol.
|
||||
if (T->isFunctionPointerType()) {
|
||||
return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
}
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
@ -298,6 +304,12 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
|
|||
QualType T = E->getType();
|
||||
SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);
|
||||
|
||||
// If T is of function pointer type, create a CodeTextRegion wrapping a
|
||||
// symbol.
|
||||
if (T->isFunctionPointerType()) {
|
||||
return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
}
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
||||
|
@ -312,6 +324,12 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
|
|||
|
||||
SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count);
|
||||
|
||||
// If T is of function pointer type, create a CodeTextRegion wrapping a
|
||||
// symbol.
|
||||
if (T->isFunctionPointerType()) {
|
||||
return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
|
||||
}
|
||||
|
||||
if (Loc::IsLocType(T))
|
||||
return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));
|
||||
|
||||
|
@ -321,6 +339,12 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
|
|||
return UnknownVal();
|
||||
}
|
||||
|
||||
SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
|
||||
CodeTextRegion* R
|
||||
= MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType()));
|
||||
return Loc::MakeVal(R);
|
||||
}
|
||||
|
||||
nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
|
||||
unsigned Bits) {
|
||||
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
|
||||
|
|
Загрузка…
Ссылка в новой задаче