summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Core/FlatStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/FlatStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/FlatStore.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/FlatStore.cpp b/lib/StaticAnalyzer/Core/FlatStore.cpp
new file mode 100644
index 0000000..99a5ead
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/FlatStore.cpp
@@ -0,0 +1,204 @@
+//=== FlatStore.cpp - Flat region-based store model -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
+#include "llvm/ADT/ImmutableIntervalMap.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace clang;
+using namespace ento;
+using llvm::Interval;
+
+// The actual store type.
+typedef llvm::ImmutableIntervalMap<SVal> BindingVal;
+typedef llvm::ImmutableMap<const MemRegion *, BindingVal> RegionBindings;
+
+namespace {
+class FlatStoreManager : public StoreManager {
+ RegionBindings::Factory RBFactory;
+ BindingVal::Factory BVFactory;
+
+public:
+ FlatStoreManager(GRStateManager &mgr)
+ : StoreManager(mgr),
+ RBFactory(mgr.getAllocator()),
+ BVFactory(mgr.getAllocator()) {}
+
+ SVal Retrieve(Store store, Loc L, QualType T);
+ StoreRef Bind(Store store, Loc L, SVal val);
+ StoreRef Remove(Store St, Loc L);
+ StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr* cl,
+ const LocationContext *LC, SVal v);
+
+ StoreRef getInitialStore(const LocationContext *InitLoc) {
+ return StoreRef(RBFactory.getEmptyMap().getRoot(), *this);
+ }
+
+ SubRegionMap *getSubRegionMap(Store store) {
+ return 0;
+ }
+
+ SVal ArrayToPointer(Loc Array);
+ StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
+ SymbolReaper& SymReaper,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots){
+ return StoreRef(store, *this);
+ }
+
+ StoreRef BindDecl(Store store, const VarRegion *VR, SVal initVal);
+
+ StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR);
+
+ typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+
+ StoreRef invalidateRegions(Store store, const MemRegion * const *I,
+ const MemRegion * const *E, const Expr *Ex,
+ unsigned Count, InvalidatedSymbols *IS,
+ bool invalidateGlobals,
+ InvalidatedRegions *Regions);
+
+ void print(Store store, llvm::raw_ostream& Out, const char* nl,
+ const char *sep);
+ void iterBindings(Store store, BindingsHandler& f);
+
+private:
+ static RegionBindings getRegionBindings(Store store) {
+ return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
+ }
+
+ class RegionInterval {
+ public:
+ const MemRegion *R;
+ Interval I;
+ RegionInterval(const MemRegion *r, int64_t s, int64_t e) : R(r), I(s, e){}
+ };
+
+ RegionInterval RegionToInterval(const MemRegion *R);
+
+ SVal RetrieveRegionWithNoBinding(const MemRegion *R, QualType T);
+};
+} // end anonymous namespace
+
+StoreManager *ento::CreateFlatStoreManager(GRStateManager &StMgr) {
+ return new FlatStoreManager(StMgr);
+}
+
+SVal FlatStoreManager::Retrieve(Store store, Loc L, QualType T) {
+ const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+ RegionInterval RI = RegionToInterval(R);
+ // FIXME: FlatStore should handle regions with unknown intervals.
+ if (!RI.R)
+ return UnknownVal();
+
+ RegionBindings B = getRegionBindings(store);
+ const BindingVal *BV = B.lookup(RI.R);
+ if (BV) {
+ const SVal *V = BVFactory.lookup(*BV, RI.I);
+ if (V)
+ return *V;
+ else
+ return RetrieveRegionWithNoBinding(R, T);
+ }
+ return RetrieveRegionWithNoBinding(R, T);
+}
+
+SVal FlatStoreManager::RetrieveRegionWithNoBinding(const MemRegion *R,
+ QualType T) {
+ if (R->hasStackNonParametersStorage())
+ return UndefinedVal();
+ else
+ return svalBuilder.getRegionValueSymbolVal(cast<TypedRegion>(R));
+}
+
+StoreRef FlatStoreManager::Bind(Store store, Loc L, SVal val) {
+ const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+ RegionBindings B = getRegionBindings(store);
+ const BindingVal *V = B.lookup(R);
+
+ BindingVal BV = BVFactory.getEmptyMap();
+ if (V)
+ BV = *V;
+
+ RegionInterval RI = RegionToInterval(R);
+ // FIXME: FlatStore should handle regions with unknown intervals.
+ if (!RI.R)
+ return StoreRef(B.getRoot(), *this);
+ BV = BVFactory.add(BV, RI.I, val);
+ B = RBFactory.add(B, RI.R, BV);
+ return StoreRef(B.getRoot(), *this);
+}
+
+StoreRef FlatStoreManager::Remove(Store store, Loc L) {
+ return StoreRef(store, *this);
+}
+
+StoreRef FlatStoreManager::BindCompoundLiteral(Store store,
+ const CompoundLiteralExpr* cl,
+ const LocationContext *LC,
+ SVal v) {
+ return StoreRef(store, *this);
+}
+
+SVal FlatStoreManager::ArrayToPointer(Loc Array) {
+ return Array;
+}
+
+StoreRef FlatStoreManager::BindDecl(Store store, const VarRegion *VR,
+ SVal initVal) {
+ return Bind(store, svalBuilder.makeLoc(VR), initVal);
+}
+
+StoreRef FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR){
+ return StoreRef(store, *this);
+}
+
+StoreRef FlatStoreManager::invalidateRegions(Store store,
+ const MemRegion * const *I,
+ const MemRegion * const *E,
+ const Expr *Ex, unsigned Count,
+ InvalidatedSymbols *IS,
+ bool invalidateGlobals,
+ InvalidatedRegions *Regions) {
+ assert(false && "Not implemented");
+ return StoreRef(store, *this);
+}
+
+void FlatStoreManager::print(Store store, llvm::raw_ostream& Out,
+ const char* nl, const char *sep) {
+}
+
+void FlatStoreManager::iterBindings(Store store, BindingsHandler& f) {
+}
+
+FlatStoreManager::RegionInterval
+FlatStoreManager::RegionToInterval(const MemRegion *R) {
+ switch (R->getKind()) {
+ case MemRegion::VarRegionKind: {
+ QualType T = cast<VarRegion>(R)->getValueType();
+ int64_t Size = Ctx.getTypeSize(T);
+ return RegionInterval(R, 0, Size-1);
+ }
+
+ case MemRegion::ElementRegionKind:
+ case MemRegion::FieldRegionKind: {
+ RegionOffset Offset = R->getAsOffset();
+ // We cannot compute offset for all regions, for example, elements
+ // with symbolic offsets.
+ if (!Offset.getRegion())
+ return RegionInterval(0, 0, 0);
+ int64_t Start = Offset.getOffset();
+ int64_t Size = Ctx.getTypeSize(cast<TypedRegion>(R)->getValueType());
+ return RegionInterval(Offset.getRegion(), Start, Start+Size);
+ }
+
+ default:
+ llvm_unreachable("Region kind unhandled.");
+ return RegionInterval(0, 0, 0);
+ }
+}
OpenPOWER on IntegriCloud