aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/RegionStore.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2008-10-08 02:50:44 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2008-10-08 02:50:44 +0000
commit178927517fa09ddbb04dc8ef725b5716c18aae21 (patch)
tree9aee69ecc87d7fabad1f51de73a4bbb5a135d8ca /lib/Analysis/RegionStore.cpp
parent8a213de1a86e5f347c6b591f52712c2fd6177cce (diff)
This is the first step to implement a field-sensitive store model. Other things are simplified: no heap shape assumption, no parameter alias assumption, etc.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57285 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r--lib/Analysis/RegionStore.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
new file mode 100644
index 0000000000..7004c5558e
--- /dev/null
+++ b/lib/Analysis/RegionStore.cpp
@@ -0,0 +1,96 @@
+//== RegionStore.cpp - Field-sensitive store model --------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a basic region store model. In this model, we do have field
+// sensitivity. But we assume nothing about the heap shape. So recursive data
+// structures are largely ignored. Basically we do 1-limiting analysis.
+// Parameter pointers are assumed with no aliasing. Pointee objects of
+// parameters are created lazily.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Analysis/PathSensitive/MemRegion.h"
+#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace clang;
+
+typedef llvm::ImmutableMap<const MemRegion*, RVal> RegionBindingsTy;
+
+namespace {
+
+class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
+ RegionBindingsTy::Factory RBFactory;
+ GRStateManager& StateMgr;
+ MemRegionManager MRMgr;
+
+public:
+ RegionStoreManager(GRStateManager& mgr)
+ : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {}
+
+ virtual ~RegionStoreManager() {}
+
+ Store SetRVal(Store St, LVal LV, RVal V);
+
+ Store getInitialStore();
+
+ static inline RegionBindingsTy GetRegionBindings(Store store) {
+ return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
+ }
+};
+
+} // end anonymous namespace
+
+Store RegionStoreManager::SetRVal(Store store, LVal LV, RVal V) {
+ assert(LV.getSubKind() == lval::MemRegionKind);
+
+ MemRegion* R = cast<lval::MemRegionVal>(LV).getRegion();
+
+ if (!R)
+ return store;
+
+ RegionBindingsTy B = GetRegionBindings(store);
+ return V.isUnknown()
+ ? RBFactory.Remove(B, R).getRoot()
+ : RBFactory.Add(B, R, V).getRoot();
+}
+
+Store RegionStoreManager::getInitialStore() {
+ typedef LiveVariables::AnalysisDataTy LVDataTy;
+ LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
+
+ Store St = RBFactory.GetEmptyMap().getRoot();
+
+ for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
+ ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
+
+ if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
+ // Punt on static variables for now.
+ if (VD->getStorageClass() == VarDecl::Static)
+ continue;
+
+ QualType T = VD->getType();
+ // Only handle pointers and integers for now.
+ if (LVal::IsLValType(T) || T->isIntegerType()) {
+ MemRegion* R = MRMgr.getVarRegion(VD);
+ // Initialize globals and parameters to symbolic values.
+ // Initialize local variables to undefined.
+ RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
+ isa<ImplicitParamDecl>(VD))
+ ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
+ : UndefinedVal();
+
+ St = SetRVal(St, lval::MemRegionVal(R), X);
+ }
+ }
+ }
+ return St;
+}