blob: 867028dc19602c87aefd8df50d3c01a4ceef81c1 [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 Kremenek2bc39c62008-08-29 00:47:32 +000059
60 /// getBindings - Returns all bindings in the specified store that bind
61 /// to the specified symbolic value.
62 virtual void getBindings(llvm::SmallVectorImpl<store::Binding>& bindings,
63 Store store, SymbolID Sym);
64
65 /// BindingAsString - Returns a string representing the given binding.
66 virtual std::string BindingAsString(store::Binding binding);
Ted Kremenek4323a572008-07-10 22:03:41 +000067};
68
69} // end anonymous namespace
70
71
Ted Kremenek5f81c442008-08-28 23:31:31 +000072StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
73 return new BasicStoreManager(StMgr);
Ted Kremenekd0c4b282008-08-25 19:33:03 +000074}
75
Ted Kremenek5f81c442008-08-28 23:31:31 +000076RegionExtent BasicStoreManager::getExtent(Region R) {
77 VarDecl* VD = (VarDecl*) R;
78 QualType T = VD->getType();
Ted Kremenekd0c4b282008-08-25 19:33:03 +000079
Ted Kremenek5f81c442008-08-28 23:31:31 +000080 // FIXME: Add support for VLAs. This may require passing in additional
81 // information, or tracking a different region type.
82 if (!T.getTypePtr()->isConstantSizeType())
83 return store::UnknownExtent();
84
85 ASTContext& C = StMgr.getContext();
86 assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type.
87 assert (T != C.VoidTy); // void not a possible VarDecl type.
88 return store::IntExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T),
89 C.VoidPtrTy));
Ted Kremenek4323a572008-07-10 22:03:41 +000090}
91
Ted Kremenek5f81c442008-08-28 23:31:31 +000092
Ted Kremenek4323a572008-07-10 22:03:41 +000093RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
94
95 if (isa<UnknownVal>(LV))
96 return UnknownVal();
97
98 assert (!isa<UndefinedVal>(LV));
99
100 switch (LV.getSubKind()) {
101
102 case lval::DeclValKind: {
103 VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
104 VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());
105 return T ? *T : UnknownVal();
106 }
107
Ted Kremenekd0c4b282008-08-25 19:33:03 +0000108 case lval::SymbolValKind:
Ted Kremenek4323a572008-07-10 22:03:41 +0000109 return UnknownVal();
Ted Kremenek4323a572008-07-10 22:03:41 +0000110
111 case lval::ConcreteIntKind:
112 // Some clients may call GetRVal with such an option simply because
113 // they are doing a quick scan through their LVals (potentially to
114 // invalidate their bindings). Just return Undefined.
115 return UndefinedVal();
116
117 case lval::ArrayOffsetKind:
118 case lval::FieldOffsetKind:
119 return UnknownVal();
120
121 case lval::FuncValKind:
122 return LV;
123
124 case lval::StringLiteralValKind:
125 // FIXME: Implement better support for fetching characters from strings.
126 return UnknownVal();
127
128 default:
129 assert (false && "Invalid LVal.");
130 break;
131 }
132
133 return UnknownVal();
134}
135
Ted Kremenekf59bf482008-07-17 18:38:48 +0000136Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
137 switch (LV.getSubKind()) {
138 case lval::DeclValKind: {
139 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000140 return V.isUnknown()
141 ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
142 : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000143 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000144 default:
145 assert ("SetRVal for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000146 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000147 }
148}
149
Ted Kremenekf59bf482008-07-17 18:38:48 +0000150Store BasicStoreManager::Remove(Store store, LVal LV) {
Ted Kremenek4323a572008-07-10 22:03:41 +0000151 switch (LV.getSubKind()) {
Ted Kremenekf59bf482008-07-17 18:38:48 +0000152 case lval::DeclValKind: {
153 VarBindingsTy B = GetVarBindings(store);
Ted Kremenek4323a572008-07-10 22:03:41 +0000154 return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000155 }
Ted Kremenek4323a572008-07-10 22:03:41 +0000156 default:
157 assert ("Remove for given LVal type not yet implemented.");
Ted Kremenekf59bf482008-07-17 18:38:48 +0000158 return store;
Ted Kremenek4323a572008-07-10 22:03:41 +0000159 }
160}
Ted Kremenekf59bf482008-07-17 18:38:48 +0000161
162Store BasicStoreManager::RemoveDeadBindings(Store store,
163 Stmt* Loc,
164 const LiveVariables& Liveness,
165 DeclRootsTy& DRoots,
166 LiveSymbolsTy& LSymbols,
167 DeadSymbolsTy& DSymbols) {
168
169 VarBindingsTy B = GetVarBindings(store);
170 typedef RVal::symbol_iterator symbol_iterator;
171
172 // Iterate over the variable bindings.
173 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
174 if (Liveness.isLive(Loc, I.getKey())) {
175 DRoots.push_back(I.getKey());
176 RVal X = I.getData();
177
178 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
179 LSymbols.insert(*SI);
180 }
181
182 // Scan for live variables and live symbols.
183 llvm::SmallPtrSet<ValueDecl*, 10> Marked;
184
185 while (!DRoots.empty()) {
186 ValueDecl* V = DRoots.back();
187 DRoots.pop_back();
188
189 if (Marked.count(V))
190 continue;
191
192 Marked.insert(V);
193
194 RVal X = GetRVal(store, lval::DeclVal(cast<VarDecl>(V)), QualType());
195
196 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
197 LSymbols.insert(*SI);
198
199 if (!isa<lval::DeclVal>(X))
200 continue;
201
202 const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
203 DRoots.push_back(LVD.getDecl());
204 }
205
206 // Remove dead variable bindings.
207 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
208 if (!Marked.count(I.getKey())) {
209 store = Remove(store, lval::DeclVal(I.getKey()));
210 RVal X = I.getData();
211
212 for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
213 if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
214 }
215
216 return store;
217}
Ted Kremenekcaa37242008-08-19 16:51:45 +0000218
219Store BasicStoreManager::getInitialStore(GRStateManager& StateMgr) {
220 // The LiveVariables information already has a compilation of all VarDecls
221 // used in the function. Iterate through this set, and "symbolicate"
222 // any VarDecl whose value originally comes from outside the function.
223
224 typedef LiveVariables::AnalysisDataTy LVDataTy;
225 LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
226
227 Store St = VBFactory.GetEmptyMap().getRoot();
228
229 for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
230 ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
231
232 if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
233 // Punt on static variables for now.
234 if (VD->getStorageClass() == VarDecl::Static)
235 continue;
236
237 // Only handle pointers and integers for now.
238 QualType T = VD->getType();
239 if (LVal::IsLValType(T) || T->isIntegerType()) {
240 // Initialize globals and parameters to symbolic values.
241 // Initialize local variables to undefined.
242 RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
243 isa<ImplicitParamDecl>(VD))
244 ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
245 : UndefinedVal();
246
247 St = SetRVal(St, lval::DeclVal(VD), X);
248 }
249 }
250 }
251 return St;
252}
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000253
Ted Kremeneke53c0692008-08-23 00:50:55 +0000254Store BasicStoreManager::AddDecl(Store store, GRStateManager& StateMgr,
255 const VarDecl* VD, Expr* Ex,
256 RVal InitVal, unsigned Count) {
257
258 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
259 SymbolManager& SymMgr = StateMgr.getSymbolManager();
260
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000261 // BasicStore does not model arrays and structs.
262 if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
263 return store;
264
265 if (VD->hasGlobalStorage()) {
266 // Handle variables with global storage: extern, static, PrivateExtern.
267
268 // FIXME:: static variables may have an initializer, but the second time a
269 // function is called those values may not be current. Currently, a function
270 // will not be called more than once.
271
272 // Static global variables should not be visited here.
273 assert(!(VD->getStorageClass() == VarDecl::Static &&
274 VD->isFileVarDecl()));
275
276 // Process static variables.
277 if (VD->getStorageClass() == VarDecl::Static) {
278 // C99: 6.7.8 Initialization
279 // If an object that has static storage duration is not initialized
280 // explicitly, then:
281 // —if it has pointer type, it is initialized to a null pointer;
282 // —if it has arithmetic type, it is initialized to (positive or
283 // unsigned) zero;
284 if (!Ex) {
285 QualType T = VD->getType();
286 if (LVal::IsLValType(T))
287 store = SetRVal(store, lval::DeclVal(VD),
288 lval::ConcreteInt(BasicVals.getValue(0, T)));
289 else if (T->isIntegerType())
290 store = SetRVal(store, lval::DeclVal(VD),
291 nonlval::ConcreteInt(BasicVals.getValue(0, T)));
292 else {
293 // assert(0 && "ignore other types of variables");
294 }
295 } else {
296 store = SetRVal(store, lval::DeclVal(VD), InitVal);
297 }
298 }
299 } else {
300 // Process local scalar variables.
301 QualType T = VD->getType();
302 if (LVal::IsLValType(T) || T->isIntegerType()) {
303 RVal V = Ex ? InitVal : UndefinedVal();
304
305 if (Ex && InitVal.isUnknown()) {
306 // EXPERIMENTAL: "Conjured" symbols.
307 SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
308
309 V = LVal::IsLValType(Ex->getType())
310 ? cast<RVal>(lval::SymbolVal(Sym))
311 : cast<RVal>(nonlval::SymbolVal(Sym));
312 }
313
314 store = SetRVal(store, lval::DeclVal(VD), V);
315 }
316 }
317
318 return store;
319}
320
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000321void BasicStoreManager::print(Store store, std::ostream& Out,
322 const char* nl, const char *sep) {
323
324 VarBindingsTy B = GetVarBindings(store);
325 Out << "Variables:" << nl;
326
327 bool isFirst = true;
328
329 for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
330 if (isFirst) isFirst = false;
331 else Out << nl;
332
333 Out << ' ' << I.getKey()->getName() << " : ";
334 I.getData().print(Out);
335 }
336}
Ted Kremenek2bc39c62008-08-29 00:47:32 +0000337
338void
339BasicStoreManager::getBindings(llvm::SmallVectorImpl<store::Binding>& bindings,
340 Store store, SymbolID Sym) {
341
342 VarBindingsTy VB((VarBindingsTy::TreeTy*) store);
343
344 for (VarBindingsTy::iterator I=VB.begin(), E=VB.end(); I!=E; ++I) {
345 if (const lval::SymbolVal* SV=dyn_cast<lval::SymbolVal>(&I->second)) {
346 if (SV->getSymbol() == Sym)
347 bindings.push_back(I->first);
348
349 continue;
350 }
351
352 if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&I->second)){
353 if (SV->getSymbol() == Sym)
354 bindings.push_back(I->first);
355 }
356 }
357}
358
359std::string BasicStoreManager::BindingAsString(store::Binding binding) {
360 // A binding is just an VarDecl*.
361 return ((VarDecl*) binding)->getName();
362}