aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/RegionStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r--lib/Analysis/RegionStore.cpp61
1 files changed, 56 insertions, 5 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 99c225f5e8..9a1f3eca34 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -26,12 +26,13 @@
using namespace clang;
+// Actual Store type.
typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
+
+// RegionView GDM stuff.
typedef llvm::ImmutableList<const MemRegion*> RegionViewTy;
typedef llvm::ImmutableMap<const MemRegion*, RegionViewTy> RegionViewMapTy;
-
static int RegionViewMapTyIndex = 0;
-
namespace clang {
template<> struct GRStateTrait<RegionViewMapTy>
: public GRStatePartialTrait<RegionViewMapTy> {
@@ -39,6 +40,18 @@ template<> struct GRStateTrait<RegionViewMapTy>
};
}
+// RegionExtents GDM stuff.
+// Currently RegionExtents are in bytes. We can change this representation when
+// there are real requirements.
+typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionExtentsTy;
+static int RegionExtentsTyIndex = 0;
+namespace clang {
+template<> struct GRStateTrait<RegionExtentsTy>
+ : public GRStatePartialTrait<RegionExtentsTy> {
+ static void* GDMIndex() { return &RegionExtentsTyIndex; }
+};
+}
+
namespace {
class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
@@ -112,6 +125,8 @@ public:
Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned Count);
+ const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent);
+
static inline RegionBindingsTy GetRegionBindings(Store store) {
return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
}
@@ -279,9 +294,38 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
}
if (const AnonTypedRegion* ATR = dyn_cast<AnonTypedRegion>(R)) {
- // FIXME: Unsupported yet.
- ATR = 0;
- return UnknownVal();
+ GRStateRef state(St, StateMgr);
+
+ // Get the size of the super region in bytes.
+ RegionExtentsTy::data_type* T
+ = state.get<RegionExtentsTy>(ATR->getSuperRegion());
+
+ assert(T && "region extent not exist");
+
+ // Assume it's ConcreteInt for now.
+ llvm::APSInt SSize = cast<nonloc::ConcreteInt>(*T).getValue();
+
+ // Get the size of the element in bits.
+ QualType ElemTy = cast<PointerType>(ATR->getType(getContext()).getTypePtr())
+ ->getPointeeType();
+
+ uint64_t X = getContext().getTypeSize(ElemTy);
+
+ const llvm::APSInt& ESize = getBasicVals().getValue(X, SSize.getBitWidth(),
+ false);
+
+ // Calculate the number of elements.
+
+ // FIXME: What do we do with signed-ness problem? Shall we make all APSInts
+ // signed?
+ if (SSize.isUnsigned())
+ SSize.setIsSigned(true);
+
+ // FIXME: move this operation into BasicVals.
+ const llvm::APSInt S =
+ (SSize * getBasicVals().getValue(8, SSize.getBitWidth(), false)) / ESize;
+
+ return NonLoc::MakeVal(getBasicVals(), S);
}
if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) {
@@ -547,6 +591,13 @@ Store RegionStoreManager::BindCompoundLiteral(Store store,
return store;
}
+const GRState* RegionStoreManager::setExtent(const GRState* St,
+ const MemRegion* R, SVal Extent) {
+ GRStateRef state(St, StateMgr);
+ return state.set<RegionExtentsTy>(R, Extent);
+}
+
+
Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
const LiveVariables& Live,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,