blob: ace8f3fbb55b378480bee09fdf3fe75e0214c719 [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
Ted Kremenek5f81c442008-08-28 23:31:31 +000014#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenekcaa37242008-08-19 16:51:45 +000015#include "clang/Analysis/PathSensitive/GRState.h"
Ted Kremenek4323a572008-07-10 22:03:41 +000016#include "llvm/ADT/ImmutableMap.h"
17#include "llvm/Support/Compiler.h"
Ted Kremeneka622d8c2008-08-19 22:24:03 +000018#include "llvm/Support/Streams.h"
Ted Kremenek4323a572008-07-10 22:03:41 +000019
20using namespace clang;
Ted Kremenek5f81c442008-08-28 23:31:31 +000021using store::Region;
22using store::RegionExtent;
Ted Kremenek4323a572008-07-10 22:03:41 +000023
24namespace {
25
26class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
27 typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
28 VarBindingsTy::Factory VBFactory;
Ted Kremenek5f81c442008-08-28 23:31:31 +000029 GRStateManager& StMgr;
Ted Kremenek4323a572008-07-10 22:03:41 +000030
31public:
Ted Kremenek5f81c442008-08-28 23:31:31 +000032 BasicStoreManager(GRStateManager& mgr) : StMgr(mgr) {}
Ted Kremenekd0c4b282008-08-25 19:33:03 +000033
Ted Kremenek4323a572008-07-10 22:03:41 +000034 virtual ~BasicStoreManager() {}
35
36 virtual RVal GetRVal(Store St, LVal LV, QualType T);
37 virtual Store SetRVal(Store St, LVal LV, RVal V);
38 virtual Store Remove(Store St, LVal LV);
39
Ted Kremenekcaa37242008-08-19 16:51:45 +000040 virtual Store getInitialStore(GRStateManager& StateMgr);
Ted Kremenekf59bf482008-07-17 18:38:48 +000041
42 virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
43 const LiveVariables& Live,
44 DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
45 DeadSymbolsTy& DSymbols);
Zhongxing Xubbe8ff42008-08-21 22:34:01 +000046
Ted Kremeneke53c0692008-08-23 00:50:55 +000047 virtual Store AddDecl(Store store, GRStateManager& StateMgr,
48 const VarDecl* VD, Expr* Ex,
Zhongxing Xubbe8ff42008-08-21 22:34:01 +000049 RVal InitVal = UndefinedVal(), unsigned Count = 0);
50
Ted Kremenekf59bf482008-07-17 18:38:48 +000051 static inline VarBindingsTy GetVarBindings(Store store) {
52 return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
Ted Kremeneka622d8c2008-08-19 22:24:03 +000053 }
54
55 virtual void print(Store store, std::ostream& Out,
56 const char* nl, const char *sep);
Ted Kremenekd0c4b282008-08-25 19:33:03 +000057
Ted Kremenek5f81c442008-08-28 23:31:31 +000058 virtual RegionExtent getExtent(Region R);
Ted Kremenek4323a572008-07-10 22:03:41 +000059};
60
61} // end anonymous namespace
62
63
Ted Kremenek5f81c442008-08-28 23:31:31 +000064StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
65 return new BasicStoreManager(StMgr);
Ted Kremenekd0c4b282008-08-25 19:33:03 +000066}
67
Ted Kremenek5f81c442008-08-28 23:31:31 +000068RegionExtent BasicStoreManager::getExtent(Region R) {
69 VarDecl* VD = (VarDecl*) R;
70 QualType T = VD->getType();
Ted Kremenekd0c4b282008-08-25 19:33:03 +000071
Ted Kremenek5f81c442008-08-28 23:31:31 +000072 // FIXME: Add support for VLAs. This may require passing in additional
73 // information, or tracking a different region type.
74 if (!T.getTypePtr()->isConstantSizeType())
75 return store::UnknownExtent();
76
77 ASTContext& C = StMgr.getContext();
78 assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type.
79 assert (T != C.VoidTy); // void not a possible VarDecl type.
80 return store::IntExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T),
81 C.VoidPtrTy));
Ted Kremenek4323a572008-07-10 22:03:41 +000082}
83
Ted Kremenek5f81c442008-08-28 23:31:31 +000084
Ted Kremenek4323a572008-07-10 22:03:41 +000085RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
86
87 if (isa<UnknownVal>(LV))
88 return UnknownVal();
89
90 assert (!isa<UndefinedVal>(LV));
91
92 switch (LV.getSubKind()) {
93
94 case lval::DeclValKind: {
95 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
96 VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());
97 return T ? *T : UnknownVal();
98 }
99
Ted Kremenekd0c4b282008-08-25 19:33:03 +0000100 case lval::SymbolValKind:
Ted Kremenek4323a572008-07-10 22:03:41 +0000101 return UnknownVal();
Ted Kremenek4323a572008-07-10 22:03:41 +0000102
103 case lval::ConcreteIntKind:
104 // Some clients may call GetRVal with such an option simply because
105 // they are doing a quick scan through their LVals (potentially to
106 // invalidate their bindings). Just return Undefined.
107 return UndefinedVal();
108
109 case lval::ArrayOffsetKind:
110 case lval::FieldOffsetKind:
111 return UnknownVal();
112
113 case lval::FuncValKind:
114 return LV;
115
116 case lval::StringLiteralValKind:
117 // FIXME: Implement better support for fetching characters from strings.
118 return UnknownVal();
119
120 default:
121 assert (false && "Invalid LVal.");
122 break;
123 }
124
125 return UnknownVal();
126}
127
Ted Kremenekf59bf482008-07-17 18:38:48 +0000128Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
129 switch (LV.getSubKind()) {
130 case lval::DeclValKind: {
131 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000132 return V.isUnknown()
133 ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
134 : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000135 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000136 default:
137 assert ("SetRVal for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000138 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000139 }
140}
141
Ted Kremenekf59bf482008-07-17 18:38:48 +0000142Store BasicStoreManager::Remove(Store store, LVal LV) {
Ted Kremenek4323a572008-07-10 22:03:41 +0000143 switch (LV.getSubKind()) {
Ted Kremenekf59bf482008-07-17 18:38:48 +0000144 case lval::DeclValKind: {
145 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000146 return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000147 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000148 default:
149 assert ("Remove for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000150 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000151 }
152}
Ted Kremenekf59bf482008-07-17 18:38:48 +0000153
154Store BasicStoreManager::RemoveDeadBindings(Store store,
155 Stmt* Loc,
156 const LiveVariables& Liveness,
157 DeclRootsTy& DRoots,
158 LiveSymbolsTy& LSymbols,
159 DeadSymbolsTy& DSymbols) {
160
161 VarBindingsTy B = GetVarBindings(store);
162 typedef RVal::symbol_iterator symbol_iterator;
163
164 // Iterate over the variable bindings.
165 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
166 if (Liveness.isLive(Loc, I.getKey())) {
167 DRoots.push_back(I.getKey());
168 RVal X = I.getData();
169
170 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
171 LSymbols.insert(*SI);
172 }
173
174 // Scan for live variables and live symbols.
175 llvm::SmallPtrSet<ValueDecl*, 10> Marked;
176
177 while (!DRoots.empty()) {
178 ValueDecl* V = DRoots.back();
179 DRoots.pop_back();
180
181 if (Marked.count(V))
182 continue;
183
184 Marked.insert(V);
185
186 RVal X = GetRVal(store, lval::DeclVal(cast<VarDecl>(V)), QualType());
187
188 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
189 LSymbols.insert(*SI);
190
191 if (!isa<lval::DeclVal>(X))
192 continue;
193
194 const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
195 DRoots.push_back(LVD.getDecl());
196 }
197
198 // Remove dead variable bindings.
199 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
200 if (!Marked.count(I.getKey())) {
201 store = Remove(store, lval::DeclVal(I.getKey()));
202 RVal X = I.getData();
203
204 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
205 if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
206 }
207
208 return store;
209}
Ted Kremenekcaa37242008-08-19 16:51:45 +0000210
211Store BasicStoreManager::getInitialStore(GRStateManager& StateMgr) {
212 // The LiveVariables information already has a compilation of all VarDecls
213 // used in the function. Iterate through this set, and "symbolicate"
214 // any VarDecl whose value originally comes from outside the function.
215
216 typedef LiveVariables::AnalysisDataTy LVDataTy;
217 LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
218
219 Store St = VBFactory.GetEmptyMap().getRoot();
220
221 for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
222 ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
223
224 if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
225 // Punt on static variables for now.
226 if (VD->getStorageClass() == VarDecl::Static)
227 continue;
228
229 // Only handle pointers and integers for now.
230 QualType T = VD->getType();
231 if (LVal::IsLValType(T) || T->isIntegerType()) {
232 // Initialize globals and parameters to symbolic values.
233 // Initialize local variables to undefined.
234 RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
235 isa<ImplicitParamDecl>(VD))
236 ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
237 : UndefinedVal();
238
239 St = SetRVal(St, lval::DeclVal(VD), X);
240 }
241 }
242 }
243 return St;
244}
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000245
Ted Kremeneke53c0692008-08-23 00:50:55 +0000246Store BasicStoreManager::AddDecl(Store store, GRStateManager& StateMgr,
247 const VarDecl* VD, Expr* Ex,
248 RVal InitVal, unsigned Count) {
249
250 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
251 SymbolManager& SymMgr = StateMgr.getSymbolManager();
252
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000253 // BasicStore does not model arrays and structs.
254 if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
255 return store;
256
257 if (VD->hasGlobalStorage()) {
258 // Handle variables with global storage: extern, static, PrivateExtern.
259
260 // FIXME:: static variables may have an initializer, but the second time a
261 // function is called those values may not be current. Currently, a function
262 // will not be called more than once.
263
264 // Static global variables should not be visited here.
265 assert(!(VD->getStorageClass() == VarDecl::Static &&
266 VD->isFileVarDecl()));
267
268 // Process static variables.
269 if (VD->getStorageClass() == VarDecl::Static) {
270 // C99: 6.7.8 Initialization
271 // If an object that has static storage duration is not initialized
272 // explicitly, then:
273 // —if it has pointer type, it is initialized to a null pointer;
274 // —if it has arithmetic type, it is initialized to (positive or
275 // unsigned) zero;
276 if (!Ex) {
277 QualType T = VD->getType();
278 if (LVal::IsLValType(T))
279 store = SetRVal(store, lval::DeclVal(VD),
280 lval::ConcreteInt(BasicVals.getValue(0, T)));
281 else if (T->isIntegerType())
282 store = SetRVal(store, lval::DeclVal(VD),
283 nonlval::ConcreteInt(BasicVals.getValue(0, T)));
284 else {
285 // assert(0 && "ignore other types of variables");
286 }
287 } else {
288 store = SetRVal(store, lval::DeclVal(VD), InitVal);
289 }
290 }
291 } else {
292 // Process local scalar variables.
293 QualType T = VD->getType();
294 if (LVal::IsLValType(T) || T->isIntegerType()) {
295 RVal V = Ex ? InitVal : UndefinedVal();
296
297 if (Ex && InitVal.isUnknown()) {
298 // EXPERIMENTAL: "Conjured" symbols.
299 SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
300
301 V = LVal::IsLValType(Ex->getType())
302 ? cast<RVal>(lval::SymbolVal(Sym))
303 : cast<RVal>(nonlval::SymbolVal(Sym));
304 }
305
306 store = SetRVal(store, lval::DeclVal(VD), V);
307 }
308 }
309
310 return store;
311}
312
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000313void BasicStoreManager::print(Store store, std::ostream& Out,
314 const char* nl, const char *sep) {
315
316 VarBindingsTy B = GetVarBindings(store);
317 Out << "Variables:" << nl;
318
319 bool isFirst = true;
320
321 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
322 if (isFirst) isFirst = false;
323 else Out << nl;
324
325 Out << ' ' << I.getKey()->getName() << " : ";
326 I.getData().print(Out);
327 }
328}