blob: 97566798c0be6e18168e07b328227c57a2ede516 [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
Ted Kremenek60dbad82008-09-03 03:06:11 +000024typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
25
Ted Kremenek4323a572008-07-10 22:03:41 +000026namespace {
27
28class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
Ted Kremenek4323a572008-07-10 22:03:41 +000029 VarBindingsTy::Factory VBFactory;
Ted Kremenek5f81c442008-08-28 23:31:31 +000030 GRStateManager& StMgr;
Ted Kremenek4323a572008-07-10 22:03:41 +000031
32public:
Ted Kremenek5f81c442008-08-28 23:31:31 +000033 BasicStoreManager(GRStateManager& mgr) : StMgr(mgr) {}
Ted Kremenekd0c4b282008-08-25 19:33:03 +000034
Ted Kremenek4323a572008-07-10 22:03:41 +000035 virtual ~BasicStoreManager() {}
36
37 virtual RVal GetRVal(Store St, LVal LV, QualType T);
38 virtual Store SetRVal(Store St, LVal LV, RVal V);
39 virtual Store Remove(Store St, LVal LV);
40
Ted Kremenekcaa37242008-08-19 16:51:45 +000041 virtual Store getInitialStore(GRStateManager& StateMgr);
Ted Kremenekf59bf482008-07-17 18:38:48 +000042
43 virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
44 const LiveVariables& Live,
45 DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
46 DeadSymbolsTy& DSymbols);
Zhongxing Xubbe8ff42008-08-21 22:34:01 +000047
Ted Kremenek60dbad82008-09-03 03:06:11 +000048 virtual void iterBindings(Store store, BindingsHandler& f);
49
Ted Kremeneke53c0692008-08-23 00:50:55 +000050 virtual Store AddDecl(Store store, GRStateManager& StateMgr,
51 const VarDecl* VD, Expr* Ex,
Zhongxing Xubbe8ff42008-08-21 22:34:01 +000052 RVal InitVal = UndefinedVal(), unsigned Count = 0);
53
Ted Kremenekf59bf482008-07-17 18:38:48 +000054 static inline VarBindingsTy GetVarBindings(Store store) {
55 return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
Ted Kremeneka622d8c2008-08-19 22:24:03 +000056 }
57
58 virtual void print(Store store, std::ostream& Out,
59 const char* nl, const char *sep);
Ted Kremenekd0c4b282008-08-25 19:33:03 +000060
Ted Kremenek5f81c442008-08-28 23:31:31 +000061 virtual RegionExtent getExtent(Region R);
Ted Kremenek2bc39c62008-08-29 00:47:32 +000062
Ted Kremenek2bc39c62008-08-29 00:47:32 +000063 /// BindingAsString - Returns a string representing the given binding.
64 virtual std::string BindingAsString(store::Binding binding);
Ted Kremenek60dbad82008-09-03 03:06:11 +000065
66 /// getRVal - Returns the bound RVal for a given binding.
67 virtual RVal getRVal(Store store, store::Binding binding);
68};
69
70class VISIBILITY_HIDDEN VarRegion : public store::Region {
71public:
72 VarRegion(VarDecl* VD) : Region(VD) {}
73 VarDecl* getDecl() const { return (VarDecl*) Data; }
74 static bool classof(const store::Region*) { return true; }
75};
76
77class VISIBILITY_HIDDEN VarBinding : public store::Binding {
78public:
79 VarBinding(VarBindingsTy::value_type* T) : store::Binding(T) {}
80
81 const VarBindingsTy::value_type_ref getValue() const {
82 return *static_cast<const VarBindingsTy::value_type*>(first);
83 }
84
85 std::string getName() const {
86 return getValue().first->getName();
87 }
88
89 RVal getRVal() const {
90 return getValue().second;
91 }
92
93 static inline bool classof(const store::Binding*) { return true; }
94};
Ted Kremenek4323a572008-07-10 22:03:41 +000095
96} // end anonymous namespace
97
98
Ted Kremenek5f81c442008-08-28 23:31:31 +000099StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
100 return new BasicStoreManager(StMgr);
Ted Kremenekd0c4b282008-08-25 19:33:03 +0000101}
102
Ted Kremenek5f81c442008-08-28 23:31:31 +0000103RegionExtent BasicStoreManager::getExtent(Region R) {
Ted Kremenek60dbad82008-09-03 03:06:11 +0000104 QualType T = cast<VarRegion>(&R)->getDecl()->getType();
Ted Kremenekd0c4b282008-08-25 19:33:03 +0000105
Ted Kremenek5f81c442008-08-28 23:31:31 +0000106 // FIXME: Add support for VLAs. This may require passing in additional
107 // information, or tracking a different region type.
108 if (!T.getTypePtr()->isConstantSizeType())
109 return store::UnknownExtent();
110
111 ASTContext& C = StMgr.getContext();
112 assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type.
113 assert (T != C.VoidTy); // void not a possible VarDecl type.
Ted Kremenek60dbad82008-09-03 03:06:11 +0000114 return store::FixedExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T),
115 C.VoidPtrTy));
Ted Kremenek4323a572008-07-10 22:03:41 +0000116}
117
Ted Kremenek5f81c442008-08-28 23:31:31 +0000118
Ted Kremenek4323a572008-07-10 22:03:41 +0000119RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
120
121 if (isa<UnknownVal>(LV))
122 return UnknownVal();
123
124 assert (!isa<UndefinedVal>(LV));
125
126 switch (LV.getSubKind()) {
127
128 case lval::DeclValKind: {
129 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
130 VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());
131 return T ? *T : UnknownVal();
132 }
133
Ted Kremenekd0c4b282008-08-25 19:33:03 +0000134 case lval::SymbolValKind:
Ted Kremenek4323a572008-07-10 22:03:41 +0000135 return UnknownVal();
Ted Kremenek4323a572008-07-10 22:03:41 +0000136
137 case lval::ConcreteIntKind:
138 // Some clients may call GetRVal with such an option simply because
139 // they are doing a quick scan through their LVals (potentially to
140 // invalidate their bindings). Just return Undefined.
141 return UndefinedVal();
142
143 case lval::ArrayOffsetKind:
144 case lval::FieldOffsetKind:
145 return UnknownVal();
146
147 case lval::FuncValKind:
148 return LV;
149
150 case lval::StringLiteralValKind:
151 // FIXME: Implement better support for fetching characters from strings.
152 return UnknownVal();
153
154 default:
155 assert (false && "Invalid LVal.");
156 break;
157 }
158
159 return UnknownVal();
160}
161
Ted Kremenekf59bf482008-07-17 18:38:48 +0000162Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
163 switch (LV.getSubKind()) {
164 case lval::DeclValKind: {
165 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000166 return V.isUnknown()
167 ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
168 : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000169 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000170 default:
171 assert ("SetRVal for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000172 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000173 }
174}
175
Ted Kremenekf59bf482008-07-17 18:38:48 +0000176Store BasicStoreManager::Remove(Store store, LVal LV) {
Ted Kremenek4323a572008-07-10 22:03:41 +0000177 switch (LV.getSubKind()) {
Ted Kremenekf59bf482008-07-17 18:38:48 +0000178 case lval::DeclValKind: {
179 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000180 return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000181 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000182 default:
183 assert ("Remove for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000184 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000185 }
186}
Ted Kremenekf59bf482008-07-17 18:38:48 +0000187
188Store BasicStoreManager::RemoveDeadBindings(Store store,
189 Stmt* Loc,
190 const LiveVariables& Liveness,
191 DeclRootsTy& DRoots,
192 LiveSymbolsTy& LSymbols,
193 DeadSymbolsTy& DSymbols) {
194
195 VarBindingsTy B = GetVarBindings(store);
196 typedef RVal::symbol_iterator symbol_iterator;
197
198 // Iterate over the variable bindings.
199 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
200 if (Liveness.isLive(Loc, I.getKey())) {
201 DRoots.push_back(I.getKey());
202 RVal X = I.getData();
203
204 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
205 LSymbols.insert(*SI);
206 }
207
208 // Scan for live variables and live symbols.
209 llvm::SmallPtrSet<ValueDecl*, 10> Marked;
210
211 while (!DRoots.empty()) {
212 ValueDecl* V = DRoots.back();
213 DRoots.pop_back();
214
215 if (Marked.count(V))
216 continue;
217
218 Marked.insert(V);
219
220 RVal X = GetRVal(store, lval::DeclVal(cast<VarDecl>(V)), QualType());
221
222 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
223 LSymbols.insert(*SI);
224
225 if (!isa<lval::DeclVal>(X))
226 continue;
227
228 const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
229 DRoots.push_back(LVD.getDecl());
230 }
231
232 // Remove dead variable bindings.
233 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
234 if (!Marked.count(I.getKey())) {
235 store = Remove(store, lval::DeclVal(I.getKey()));
236 RVal X = I.getData();
237
238 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
239 if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
240 }
241
242 return store;
243}
Ted Kremenekcaa37242008-08-19 16:51:45 +0000244
245Store BasicStoreManager::getInitialStore(GRStateManager& StateMgr) {
246 // The LiveVariables information already has a compilation of all VarDecls
247 // used in the function. Iterate through this set, and "symbolicate"
248 // any VarDecl whose value originally comes from outside the function.
249
250 typedef LiveVariables::AnalysisDataTy LVDataTy;
251 LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
252
253 Store St = VBFactory.GetEmptyMap().getRoot();
254
255 for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
256 ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
257
258 if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
259 // Punt on static variables for now.
260 if (VD->getStorageClass() == VarDecl::Static)
261 continue;
262
263 // Only handle pointers and integers for now.
264 QualType T = VD->getType();
265 if (LVal::IsLValType(T) || T->isIntegerType()) {
266 // Initialize globals and parameters to symbolic values.
267 // Initialize local variables to undefined.
268 RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
269 isa<ImplicitParamDecl>(VD))
270 ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
271 : UndefinedVal();
272
273 St = SetRVal(St, lval::DeclVal(VD), X);
274 }
275 }
276 }
277 return St;
278}
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000279
Ted Kremeneke53c0692008-08-23 00:50:55 +0000280Store BasicStoreManager::AddDecl(Store store, GRStateManager& StateMgr,
281 const VarDecl* VD, Expr* Ex,
282 RVal InitVal, unsigned Count) {
283
284 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
285 SymbolManager& SymMgr = StateMgr.getSymbolManager();
286
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000287 // BasicStore does not model arrays and structs.
288 if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
289 return store;
290
291 if (VD->hasGlobalStorage()) {
292 // Handle variables with global storage: extern, static, PrivateExtern.
293
294 // FIXME:: static variables may have an initializer, but the second time a
295 // function is called those values may not be current. Currently, a function
296 // will not be called more than once.
297
298 // Static global variables should not be visited here.
299 assert(!(VD->getStorageClass() == VarDecl::Static &&
300 VD->isFileVarDecl()));
301
302 // Process static variables.
303 if (VD->getStorageClass() == VarDecl::Static) {
304 // C99: 6.7.8 Initialization
305 // If an object that has static storage duration is not initialized
306 // explicitly, then:
307 // —if it has pointer type, it is initialized to a null pointer;
308 // —if it has arithmetic type, it is initialized to (positive or
309 // unsigned) zero;
310 if (!Ex) {
311 QualType T = VD->getType();
312 if (LVal::IsLValType(T))
313 store = SetRVal(store, lval::DeclVal(VD),
314 lval::ConcreteInt(BasicVals.getValue(0, T)));
315 else if (T->isIntegerType())
316 store = SetRVal(store, lval::DeclVal(VD),
317 nonlval::ConcreteInt(BasicVals.getValue(0, T)));
318 else {
319 // assert(0 && "ignore other types of variables");
320 }
321 } else {
322 store = SetRVal(store, lval::DeclVal(VD), InitVal);
323 }
324 }
325 } else {
326 // Process local scalar variables.
327 QualType T = VD->getType();
328 if (LVal::IsLValType(T) || T->isIntegerType()) {
329 RVal V = Ex ? InitVal : UndefinedVal();
330
331 if (Ex && InitVal.isUnknown()) {
332 // EXPERIMENTAL: "Conjured" symbols.
333 SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
334
335 V = LVal::IsLValType(Ex->getType())
336 ? cast<RVal>(lval::SymbolVal(Sym))
337 : cast<RVal>(nonlval::SymbolVal(Sym));
338 }
339
340 store = SetRVal(store, lval::DeclVal(VD), V);
341 }
342 }
343
344 return store;
345}
346
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000347void BasicStoreManager::print(Store store, std::ostream& Out,
348 const char* nl, const char *sep) {
349
350 VarBindingsTy B = GetVarBindings(store);
351 Out << "Variables:" << nl;
352
353 bool isFirst = true;
354
355 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
356 if (isFirst) isFirst = false;
357 else Out << nl;
358
359 Out << ' ' << I.getKey()->getName() << " : ";
360 I.getData().print(Out);
361 }
362}
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000363
Ted Kremenek60dbad82008-09-03 03:06:11 +0000364
365void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
366 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000367
Ted Kremenek60dbad82008-09-03 03:06:11 +0000368 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
369 VarBinding binding(&(*I));
370 f.HandleBinding(*this, store, binding);
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000371 }
372}
373
Ted Kremenek60dbad82008-09-03 03:06:11 +0000374
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000375std::string BasicStoreManager::BindingAsString(store::Binding binding) {
Ted Kremenek60dbad82008-09-03 03:06:11 +0000376 return cast<VarBinding>(binding).getName();
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000377}
Ted Kremenek60dbad82008-09-03 03:06:11 +0000378
379RVal BasicStoreManager::getRVal(Store store, store::Binding binding) {
380 return cast<VarBinding>(binding).getRVal();
381}
382
383//==------------------------------------------------------------------------==//
384// Generic store operations.
385//==------------------------------------------------------------------------==//
386
387namespace {
388class VISIBILITY_HIDDEN GetBindingsIterator : public StoreManager::BindingsHandler {
389 SymbolID Sym;
390 llvm::SmallVectorImpl<store::Binding>& bindings;
391public:
392 GetBindingsIterator(SymbolID s, llvm::SmallVectorImpl<store::Binding>& b)
393 : Sym(s), bindings(b) {}
394
395 virtual bool HandleBinding(StoreManager& SMgr, Store store,
396 store::Binding binding) {
397
398 RVal V = SMgr.getRVal(store, binding);
399
400 if (const lval::SymbolVal* SV=dyn_cast<lval::SymbolVal>(&V)) {
401 if (SV->getSymbol() == Sym)
402 bindings.push_back(binding);
403 }
404 else if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&V)){
405 if (SV->getSymbol() == Sym)
406 bindings.push_back(binding);
407 }
408
409 return true;
410 }
411};
412} // end anonymous namespace
413
414void StoreManager::getBindings(llvm::SmallVectorImpl<store::Binding>& bindings,
415 Store store, SymbolID Sym) {
416
417 GetBindingsIterator BI(Sym, bindings);
418 iterBindings(store, BI);
419}
420
421StoreManager::BindingsHandler::~BindingsHandler() {}
422