blob: 38c1db70f15bc6e051b2429c984352d084ac152a [file] [log] [blame]
Ted Kremenek4323a572008-07-10 22:03:41 +00001//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defined the BasicStore and BasicStoreManager classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Analysis/PathSensitive/BasicStore.h"
15#include "llvm/ADT/ImmutableMap.h"
16#include "llvm/Support/Compiler.h"
17
18using namespace clang;
19
20namespace {
21
22class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
23 typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
24 VarBindingsTy::Factory VBFactory;
25
26public:
27 BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {}
28 virtual ~BasicStoreManager() {}
29
30 virtual RVal GetRVal(Store St, LVal LV, QualType T);
31 virtual Store SetRVal(Store St, LVal LV, RVal V);
32 virtual Store Remove(Store St, LVal LV);
33
34 virtual Store getInitialStore() {
35 return VBFactory.GetEmptyMap().getRoot();
36 }
37};
38
39} // end anonymous namespace
40
41
42StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) {
43 return new BasicStoreManager(A);
44}
45
46RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
47
48 if (isa<UnknownVal>(LV))
49 return UnknownVal();
50
51 assert (!isa<UndefinedVal>(LV));
52
53 switch (LV.getSubKind()) {
54
55 case lval::DeclValKind: {
56 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
57 VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());
58 return T ? *T : UnknownVal();
59 }
60
61 case lval::SymbolValKind: {
62
63 // FIXME: This is a broken representation of memory, and is prone
64 // to crashing the analyzer when addresses to symbolic values are
65 // passed through casts. We need a better representation of symbolic
66 // memory (or just memory in general); probably we should do this
67 // as a plugin class (similar to GRTransferFuncs).
68
69#if 0
70 const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
71 assert (T.getTypePtr());
72
73 // Punt on "symbolic" function pointers.
74 if (T->isFunctionType())
75 return UnknownVal();
76
77 if (T->isPointerType())
78 return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
79 else
80 return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
81#endif
82
83 return UnknownVal();
84 }
85
86 case lval::ConcreteIntKind:
87 // Some clients may call GetRVal with such an option simply because
88 // they are doing a quick scan through their LVals (potentially to
89 // invalidate their bindings). Just return Undefined.
90 return UndefinedVal();
91
92 case lval::ArrayOffsetKind:
93 case lval::FieldOffsetKind:
94 return UnknownVal();
95
96 case lval::FuncValKind:
97 return LV;
98
99 case lval::StringLiteralValKind:
100 // FIXME: Implement better support for fetching characters from strings.
101 return UnknownVal();
102
103 default:
104 assert (false && "Invalid LVal.");
105 break;
106 }
107
108 return UnknownVal();
109}
110
111Store BasicStoreManager::SetRVal(Store St, LVal LV, RVal V) {
112
113 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
114
115 switch (LV.getSubKind()) {
116
117 case lval::DeclValKind:
118 return V.isUnknown()
119 ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
120 : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
121
122 default:
123 assert ("SetRVal for given LVal type not yet implemented.");
124 return St;
125 }
126}
127
128Store BasicStoreManager::Remove(Store St, LVal LV) {
129
130 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
131
132 switch (LV.getSubKind()) {
133
134 case lval::DeclValKind:
135 return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
136
137 default:
138 assert ("Remove for given LVal type not yet implemented.");
139 return St;
140 }
141}