aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-02-05 06:57:29 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-02-05 06:57:29 +0000
commit026c66395b88a09437319139a43b090093f7e1dd (patch)
tree7955f6fdf8c03de8d27a80ed0adf8d2e898e3e84
parentcf70177a9cf6c35b27e73cf58f82dd4d6b0fa354 (diff)
Make SymbolicRegion subclass TypedRegion, for symbols usually have types, so
do the symblic regions associated with them and we need them to be typed. Current SymbolicRegion::getRValueType() method is very restricting. It may be modified when we are more clear about what could be the types of symblic regions. BasicConstraintManager::Assume() is changed due to that now SymblicRegion is a subclass of SubRegion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63844 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h64
-rw-r--r--lib/Analysis/BasicConstraintManager.cpp15
-rw-r--r--lib/Analysis/BasicStore.cpp6
-rw-r--r--lib/Analysis/MemRegion.cpp32
-rw-r--r--lib/Analysis/RegionStore.cpp6
5 files changed, 75 insertions, 48 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 8a62eff7a9..ba08e38387 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -38,10 +38,11 @@ class MemRegionManager;
/// MemRegion - The root abstract class for all memory regions.
class MemRegion : public llvm::FoldingSetNode {
public:
- enum Kind { MemSpaceRegionKind, SymbolicRegionKind,
+ enum Kind { MemSpaceRegionKind,
AllocaRegionKind,
// Typed regions.
BEG_TYPED_REGIONS,
+ SymbolicRegionKind,
CompoundLiteralRegionKind,
StringRegionKind, ElementRegionKind,
AnonTypedRegionKind,
@@ -103,7 +104,7 @@ public:
bool isSubRegionOf(const MemRegion* R) const;
static bool classof(const MemRegion* R) {
- return R->getKind() > SymbolicRegionKind;
+ return R->getKind() > MemSpaceRegionKind;
}
};
@@ -135,32 +136,6 @@ public:
}
};
-/// 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
-/// map the concept of symbolic values into the domain of regions. Symbolic
-/// regions do not need to be typed.
-class SymbolicRegion : public MemRegion {
-protected:
- const SymbolRef sym;
-
-public:
- SymbolicRegion(const SymbolRef s) : MemRegion(SymbolicRegionKind), sym(s) {}
-
- SymbolRef getSymbol() const {
- return sym;
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym);
-
- void print(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == SymbolicRegionKind;
- }
-};
-
/// TypedRegion - An abstract class representing regions that are typed.
class TypedRegion : public SubRegion {
protected:
@@ -188,6 +163,37 @@ public:
}
};
+/// 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
+/// map the concept of symbolic values into the domain of regions. Symbolic
+/// regions do not need to be typed.
+class SymbolicRegion : public TypedRegion {
+protected:
+ const SymbolRef sym;
+ const SymbolManager& SymMgr;
+
+public:
+ SymbolicRegion(const SymbolRef s, const SymbolManager& mgr, MemRegion* sreg)
+ : TypedRegion(sreg, SymbolicRegionKind), sym(s), SymMgr(mgr) {}
+
+ SymbolRef getSymbol() const {
+ return sym;
+ }
+
+ QualType getRValueType(ASTContext& C) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym);
+
+ void print(llvm::raw_ostream& os) const;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == SymbolicRegionKind;
+ }
+};
+
/// StringRegion - Region associated with a StringLiteral.
class StringRegion : public TypedRegion {
friend class MemRegionManager;
@@ -492,7 +498,7 @@ public:
getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
- SymbolicRegion* getSymbolicRegion(const SymbolRef sym);
+ SymbolicRegion* getSymbolicRegion(const SymbolRef sym, const SymbolManager&);
StringRegion* getStringRegion(const StringLiteral* Str);
diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp
index 0c98bf6450..58c4727d51 100644
--- a/lib/Analysis/BasicConstraintManager.cpp
+++ b/lib/Analysis/BasicConstraintManager.cpp
@@ -165,17 +165,14 @@ const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond,
// FIXME: Should this go into the storemanager?
const MemRegion* R = cast<loc::MemRegionVal>(Cond).getRegion();
-
- while (R) {
- if (const SubRegion* SubR = dyn_cast<SubRegion>(R)) {
- R = SubR->getSuperRegion();
- continue;
- }
- else if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
+ const SubRegion* SubR = dyn_cast<SubRegion>(R);
+
+ while (SubR) {
+ // FIXME: now we only find the first symbolic region.
+ if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(SubR))
return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption,
isFeasible);
-
- break;
+ SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
}
// FALL-THROUGH.
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 2feea594b8..ad542b884a 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -173,7 +173,8 @@ SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base,
switch(BaseL.getSubKind()) {
case loc::SymbolValKind:
- BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol());
+ BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol(),
+ StateMgr.getSymbolManager());
break;
case loc::GotoLabelKind:
@@ -218,7 +219,8 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base,
// Create a region to represent this symbol.
// FIXME: In the future we may just use symbolic regions instead of
// SymbolVals to reason about symbolic memory chunks.
- const MemRegion* SymR = MRMgr.getSymbolicRegion(Sym);
+ const MemRegion* SymR = MRMgr.getSymbolicRegion(Sym,
+ StateMgr.getSymbolManager());
// Layered a typed region on top of this.
QualType T = StateMgr.getSymbolManager().getType(Sym);
BaseR = MRMgr.getAnonTypedRegion(T, SymR);
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 82f4423541..e41c5f937b 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -107,6 +107,28 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
ElementRegion::ProfileRegion(ID, Index, superRegion);
}
+//===----------------------------------------------------------------------===//
+// getLValueType() and getRValueType()
+//===----------------------------------------------------------------------===//
+
+QualType SymbolicRegion::getRValueType(ASTContext& C) const {
+ const SymbolData& data = SymMgr.getSymbolData(sym);
+
+ // FIXME: We could use the SymbolManager::getType() directly. But that
+ // would hide the assumptions we made here. What is the type of a symbolic
+ // region is unclear for other cases.
+
+ // For now we assume the symbol is a typed region rvalue.
+ const TypedRegion* R
+ = cast<TypedRegion>(cast<SymbolRegionRValue>(data).getRegion());
+
+ // Assume the region rvalue has a pointer type, only then we could have a
+ // symbolic region associated with it.
+ PointerType* PTy = cast<PointerType>(R->getRValueType(C).getTypePtr());
+
+ return PTy->getPointeeType();
+}
+
QualType ElementRegion::getRValueType(ASTContext& C) const {
// Strip off typedefs from the ArrayRegion's RvalueType.
QualType T = getArrayRegion()->getRValueType(C)->getDesugaredType();
@@ -119,10 +141,6 @@ QualType ElementRegion::getRValueType(ASTContext& C) const {
return T;
}
-//===----------------------------------------------------------------------===//
-// getLValueType() and getRValueType()
-//===----------------------------------------------------------------------===//
-
QualType StringRegion::getRValueType(ASTContext& C) const {
return Str->getType();
}
@@ -308,7 +326,8 @@ MemRegionManager::getElementRegion(SVal Idx, const TypedRegion* superRegion){
}
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
-SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym) {
+SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym,
+ const SymbolManager& mgr) {
llvm::FoldingSetNodeID ID;
SymbolicRegion::ProfileRegion(ID, sym);
@@ -319,7 +338,8 @@ SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym) {
if (!R) {
R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
- new (R) SymbolicRegion(sym);
+ // SymbolicRegion's storage class is usually unknown.
+ new (R) SymbolicRegion(sym, mgr, getUnknownRegion());
Regions.InsertNode(R, InsertPos);
}
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 8d36d10a8a..e640087acb 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -312,7 +312,8 @@ SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base,
break;
case loc::SymbolValKind:
- BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol());
+ BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol(),
+ StateMgr.getSymbolManager());
break;
case loc::GotoLabelKind:
@@ -701,7 +702,8 @@ Store RegionStoreManager::Remove(Store store, Loc L) {
if (isa<loc::MemRegionVal>(L))
R = cast<loc::MemRegionVal>(L).getRegion();
else if (isa<loc::SymbolVal>(L))
- R = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(L).getSymbol());
+ R = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(L).getSymbol(),
+ StateMgr.getSymbolManager());
if (R) {
RegionBindingsTy B = GetRegionBindings(store);