summaryrefslogtreecommitdiffstats
path: root/clang/lib/Checker/FlatStore.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-08-02 04:56:14 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-08-02 04:56:14 +0000
commitfd91d27630c6236f13a3da1a79db22ede762a212 (patch)
treead1408f33e34c55564d895cba967c9c02566a039 /clang/lib/Checker/FlatStore.cpp
parent460ad41d6d2e6af29d11b3e16345123503da19c4 (diff)
downloadbcm5719-llvm-fd91d27630c6236f13a3da1a79db22ede762a212.tar.gz
bcm5719-llvm-fd91d27630c6236f13a3da1a79db22ede762a212.zip
Improve flat store: MemRegion::getAsOffset() computes a region's offset within
the top-level object. FlatStore now can bind and retrieve element and field regions. PR7297 is fixed by flat store. llvm-svn: 110020
Diffstat (limited to 'clang/lib/Checker/FlatStore.cpp')
-rw-r--r--clang/lib/Checker/FlatStore.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/clang/lib/Checker/FlatStore.cpp b/clang/lib/Checker/FlatStore.cpp
index 64575b3c978..51c537ecfad 100644
--- a/clang/lib/Checker/FlatStore.cpp
+++ b/clang/lib/Checker/FlatStore.cpp
@@ -74,7 +74,14 @@ private:
return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
}
- Interval RegionToInterval(const MemRegion *R);
+ class RegionInterval {
+ public:
+ const MemRegion *R;
+ Interval I;
+ RegionInterval(const MemRegion *r, uint64_t s, uint64_t e) : R(r), I(s, e){}
+ };
+
+ RegionInterval RegionToInterval(const MemRegion *R);
SVal RetrieveRegionWithNoBinding(const MemRegion *R, QualType T);
};
@@ -86,11 +93,14 @@ StoreManager *clang::CreateFlatStoreManager(GRStateManager &StMgr) {
SVal FlatStoreManager::Retrieve(Store store, Loc L, QualType T) {
const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
- Interval I = RegionToInterval(R);
+ RegionInterval RI = RegionToInterval(R);
+
+ assert(RI.R && "should handle regions with unknown interval");
+
RegionBindings B = getRegionBindings(store);
- const BindingVal *BV = B.lookup(R);
+ const BindingVal *BV = B.lookup(RI.R);
if (BV) {
- const SVal *V = BVFactory.Lookup(*BV, I);
+ const SVal *V = BVFactory.Lookup(*BV, RI.I);
if (V)
return *V;
else
@@ -116,9 +126,10 @@ Store FlatStoreManager::Bind(Store store, Loc L, SVal val) {
if (V)
BV = *V;
- Interval I = RegionToInterval(R);
- BV = BVFactory.Add(BV, I, val);
- B = RBFactory.Add(B, R, BV);
+ RegionInterval RI = RegionToInterval(R);
+ assert(RI.R && "should handle regions with unknown interval");
+ BV = BVFactory.Add(BV, RI.I, val);
+ B = RBFactory.Add(B, RI.R, BV);
return B.getRoot();
}
@@ -139,7 +150,7 @@ SVal FlatStoreManager::ArrayToPointer(Loc Array) {
Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR,
SVal initVal) {
- return store;
+ return Bind(store, ValMgr.makeLoc(VR), initVal);
}
Store FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR) {
@@ -170,15 +181,30 @@ void FlatStoreManager::print(Store store, llvm::raw_ostream& Out,
void FlatStoreManager::iterBindings(Store store, BindingsHandler& f) {
}
-Interval FlatStoreManager::RegionToInterval(const MemRegion *R) {
+FlatStoreManager::RegionInterval
+FlatStoreManager::RegionToInterval(const MemRegion *R) {
switch (R->getKind()) {
case MemRegion::VarRegionKind: {
QualType T = cast<VarRegion>(R)->getValueType(Ctx);
uint64_t Size = Ctx.getTypeSize(T);
- return Interval(0, Size-1);
+ return RegionInterval(R, 0, Size-1);
}
+
+ case MemRegion::ElementRegionKind:
+ case MemRegion::FieldRegionKind: {
+ const TypedRegion *TR = cast<TypedRegion>(R);
+ RegionOffset Offset = TR->getAsOffset();
+ // We cannot compute offset for all ElementRegions, for example, elements
+ // with symbolic offsets.
+ if (!Offset.getRegion())
+ return RegionInterval(0, 0, 0);
+ uint64_t Start = Offset.getOffset();
+ uint64_t Size = Ctx.getTypeSize(TR->getValueType(Ctx));
+ return RegionInterval(Offset.getRegion(), Start, Start+Size);
+ }
+
default:
llvm_unreachable("Region kind unhandled.");
- return Interval(0, 0);
+ return RegionInterval(0, 0, 0);
}
}
OpenPOWER on IntegriCloud