aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/BasicStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/BasicStore.cpp')
-rw-r--r--lib/Analysis/BasicStore.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
new file mode 100644
index 0000000000..38c1db70f1
--- /dev/null
+++ b/lib/Analysis/BasicStore.cpp
@@ -0,0 +1,141 @@
+//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defined the BasicStore and BasicStoreManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/BasicStore.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace clang;
+
+namespace {
+
+class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
+ typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
+ VarBindingsTy::Factory VBFactory;
+
+public:
+ BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {}
+ virtual ~BasicStoreManager() {}
+
+ virtual RVal GetRVal(Store St, LVal LV, QualType T);
+ virtual Store SetRVal(Store St, LVal LV, RVal V);
+ virtual Store Remove(Store St, LVal LV);
+
+ virtual Store getInitialStore() {
+ return VBFactory.GetEmptyMap().getRoot();
+ }
+};
+
+} // end anonymous namespace
+
+
+StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) {
+ return new BasicStoreManager(A);
+}
+
+RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
+
+ if (isa<UnknownVal>(LV))
+ return UnknownVal();
+
+ assert (!isa<UndefinedVal>(LV));
+
+ switch (LV.getSubKind()) {
+
+ case lval::DeclValKind: {
+ VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+ VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());
+ return T ? *T : UnknownVal();
+ }
+
+ case lval::SymbolValKind: {
+
+ // FIXME: This is a broken representation of memory, and is prone
+ // to crashing the analyzer when addresses to symbolic values are
+ // passed through casts. We need a better representation of symbolic
+ // memory (or just memory in general); probably we should do this
+ // as a plugin class (similar to GRTransferFuncs).
+
+#if 0
+ const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
+ assert (T.getTypePtr());
+
+ // Punt on "symbolic" function pointers.
+ if (T->isFunctionType())
+ return UnknownVal();
+
+ if (T->isPointerType())
+ return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
+ else
+ return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
+#endif
+
+ return UnknownVal();
+ }
+
+ case lval::ConcreteIntKind:
+ // Some clients may call GetRVal with such an option simply because
+ // they are doing a quick scan through their LVals (potentially to
+ // invalidate their bindings). Just return Undefined.
+ return UndefinedVal();
+
+ case lval::ArrayOffsetKind:
+ case lval::FieldOffsetKind:
+ return UnknownVal();
+
+ case lval::FuncValKind:
+ return LV;
+
+ case lval::StringLiteralValKind:
+ // FIXME: Implement better support for fetching characters from strings.
+ return UnknownVal();
+
+ default:
+ assert (false && "Invalid LVal.");
+ break;
+ }
+
+ return UnknownVal();
+}
+
+Store BasicStoreManager::SetRVal(Store St, LVal LV, RVal V) {
+
+ VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+
+ switch (LV.getSubKind()) {
+
+ case lval::DeclValKind:
+ return V.isUnknown()
+ ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
+ : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
+
+ default:
+ assert ("SetRVal for given LVal type not yet implemented.");
+ return St;
+ }
+}
+
+Store BasicStoreManager::Remove(Store St, LVal LV) {
+
+ VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+
+ switch (LV.getSubKind()) {
+
+ case lval::DeclValKind:
+ return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
+
+ default:
+ assert ("Remove for given LVal type not yet implemented.");
+ return St;
+ }
+}