aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-04-10 08:45:10 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-04-10 08:45:10 +0000
commitec13d9206645af07ef7c571405893b8d901de151 (patch)
treebe346b26868811c18a726420ad7d3c931d0331b3
parentcf665e1fbaf14b5f9e4ec44622eb2053c251edcb (diff)
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
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h61
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h2
-rw-r--r--lib/Analysis/MemRegion.cpp48
-rw-r--r--lib/Analysis/SVals.cpp24
4 files changed, 134 insertions, 1 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 766c0918d1..1c97f1737c 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -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:
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h
index f83b02c227..415969b54d 100644
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/include/clang/Analysis/PathSensitive/ValueManager.h
@@ -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
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 7c13f0701e..c8a43a556d 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -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;
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index 3e958ba801..572d5ec555 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -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));