blob: dc0cac887797b172e648d45f49359421657b9706 [file] [log] [blame]
Zhongxing Xu17892752008-10-08 02:50:44 +00001//== RegionStore.cpp - Field-sensitive store model --------------*- 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 defines a basic region store model. In this model, we do have field
11// sensitivity. But we assume nothing about the heap shape. So recursive data
12// structures are largely ignored. Basically we do 1-limiting analysis.
13// Parameter pointers are assumed with no aliasing. Pointee objects of
14// parameters are created lazily.
15//
16//===----------------------------------------------------------------------===//
17#include "clang/Analysis/PathSensitive/MemRegion.h"
18#include "clang/Analysis/PathSensitive/GRState.h"
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000019#include "clang/Analysis/PathSensitive/GRStateTrait.h"
Zhongxing Xu17892752008-10-08 02:50:44 +000020#include "clang/Analysis/Analyses/LiveVariables.h"
Zhongxing Xu41fd0182009-05-06 11:51:48 +000021#include "clang/Basic/TargetInfo.h"
Zhongxing Xu17892752008-10-08 02:50:44 +000022
23#include "llvm/ADT/ImmutableMap.h"
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000024#include "llvm/ADT/ImmutableList.h"
Zhongxing Xua071eb02008-10-24 06:01:33 +000025#include "llvm/Support/raw_ostream.h"
Zhongxing Xu17892752008-10-08 02:50:44 +000026#include "llvm/Support/Compiler.h"
27
28using namespace clang;
29
Ted Kremenek356e9d62009-07-22 04:35:42 +000030#define USE_REGION_CASTS 0
31#define HEAP_UNDEFINED 0
32
Zhongxing Xubaf03a72008-11-24 09:44:56 +000033// Actual Store type.
Zhongxing Xu1c96b242008-10-17 05:57:07 +000034typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
Zhongxing Xubaf03a72008-11-24 09:44:56 +000035
Ted Kremenek50dc1b32008-12-24 01:05:03 +000036//===----------------------------------------------------------------------===//
Ted Kremenek9af46f52009-06-16 22:36:44 +000037// Fine-grained control of RegionStoreManager.
38//===----------------------------------------------------------------------===//
39
40namespace {
41struct VISIBILITY_HIDDEN minimal_features_tag {};
42struct VISIBILITY_HIDDEN maximal_features_tag {};
43
44class VISIBILITY_HIDDEN RegionStoreFeatures {
45 bool SupportsFields;
46 bool SupportsRemaining;
47
48public:
49 RegionStoreFeatures(minimal_features_tag) :
50 SupportsFields(false), SupportsRemaining(false) {}
51
52 RegionStoreFeatures(maximal_features_tag) :
53 SupportsFields(true), SupportsRemaining(false) {}
54
55 void enableFields(bool t) { SupportsFields = t; }
56
57 bool supportsFields() const { return SupportsFields; }
58 bool supportsRemaining() const { return SupportsRemaining; }
59};
60}
61
62//===----------------------------------------------------------------------===//
Ted Kremenek50dc1b32008-12-24 01:05:03 +000063// Region "Views"
64//===----------------------------------------------------------------------===//
65//
66// MemRegions can be layered on top of each other. This GDM entry tracks
67// what are the MemRegions that layer a given MemRegion.
68//
Zhongxing Xu5834ed62009-01-13 01:49:57 +000069typedef llvm::ImmutableSet<const MemRegion*> RegionViews;
Ted Kremenek50dc1b32008-12-24 01:05:03 +000070namespace { class VISIBILITY_HIDDEN RegionViewMap {}; }
71static int RegionViewMapIndex = 0;
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000072namespace clang {
Ted Kremenek50dc1b32008-12-24 01:05:03 +000073 template<> struct GRStateTrait<RegionViewMap>
74 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*,
75 RegionViews> > {
76
77 static void* GDMIndex() { return &RegionViewMapIndex; }
78 };
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000079}
Zhongxing Xu17892752008-10-08 02:50:44 +000080
Zhongxing Xu20794942009-05-06 08:33:50 +000081// RegionCasts records the current cast type of a region.
82namespace { class VISIBILITY_HIDDEN RegionCasts {}; }
83static int RegionCastsIndex = 0;
84namespace clang {
85 template<> struct GRStateTrait<RegionCasts>
86 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*,
87 QualType> > {
88 static void* GDMIndex() { return &RegionCastsIndex; }
89 };
90}
91
Ted Kremenek50dc1b32008-12-24 01:05:03 +000092//===----------------------------------------------------------------------===//
93// Region "Extents"
94//===----------------------------------------------------------------------===//
95//
96// MemRegions represent chunks of memory with a size (their "extent"). This
97// GDM entry tracks the extents for regions. Extents are in bytes.
Ted Kremenekd6cfbe42009-01-07 22:18:50 +000098//
Ted Kremenek50dc1b32008-12-24 01:05:03 +000099namespace { class VISIBILITY_HIDDEN RegionExtents {}; }
100static int RegionExtentsIndex = 0;
Zhongxing Xubaf03a72008-11-24 09:44:56 +0000101namespace clang {
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000102 template<> struct GRStateTrait<RegionExtents>
103 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, SVal> > {
104 static void* GDMIndex() { return &RegionExtentsIndex; }
105 };
Zhongxing Xubaf03a72008-11-24 09:44:56 +0000106}
107
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000108//===----------------------------------------------------------------------===//
Zhongxing Xu5834ed62009-01-13 01:49:57 +0000109// Regions with default values.
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000110//===----------------------------------------------------------------------===//
111//
Zhongxing Xu5834ed62009-01-13 01:49:57 +0000112// This GDM entry tracks what regions have a default value if they have no bound
113// value and have not been killed.
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000114//
115namespace { class VISIBILITY_HIDDEN RegionDefaultValue {}; }
116static int RegionDefaultValueIndex = 0;
117namespace clang {
118 template<> struct GRStateTrait<RegionDefaultValue>
119 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, SVal> > {
120 static void* GDMIndex() { return &RegionDefaultValueIndex; }
121 };
122}
123
124//===----------------------------------------------------------------------===//
125// Main RegionStore logic.
126//===----------------------------------------------------------------------===//
Ted Kremenekc48ea6e2008-12-04 02:08:27 +0000127
Zhongxing Xu17892752008-10-08 02:50:44 +0000128namespace {
129
Ted Kremenek59e8f112009-03-03 01:35:36 +0000130class VISIBILITY_HIDDEN RegionStoreSubRegionMap : public SubRegionMap {
131 typedef llvm::DenseMap<const MemRegion*,
132 llvm::ImmutableSet<const MemRegion*> > Map;
133
134 llvm::ImmutableSet<const MemRegion*>::Factory F;
135 Map M;
136
137public:
138 void add(const MemRegion* Parent, const MemRegion* SubRegion) {
139 Map::iterator I = M.find(Parent);
140 M.insert(std::make_pair(Parent,
141 F.Add(I == M.end() ? F.GetEmptySet() : I->second, SubRegion)));
142 }
143
144 ~RegionStoreSubRegionMap() {}
145
Ted Kremenek5dc27462009-03-03 02:51:43 +0000146 bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
Ted Kremenek59e8f112009-03-03 01:35:36 +0000147 Map::iterator I = M.find(Parent);
148
149 if (I == M.end())
Ted Kremenek5dc27462009-03-03 02:51:43 +0000150 return true;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000151
152 llvm::ImmutableSet<const MemRegion*> S = I->second;
153 for (llvm::ImmutableSet<const MemRegion*>::iterator SI=S.begin(),SE=S.end();
154 SI != SE; ++SI) {
155 if (!V.Visit(Parent, *SI))
Ted Kremenek5dc27462009-03-03 02:51:43 +0000156 return false;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000157 }
Ted Kremenek5dc27462009-03-03 02:51:43 +0000158
159 return true;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000160 }
161};
162
Zhongxing Xu17892752008-10-08 02:50:44 +0000163class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
Ted Kremenek9af46f52009-06-16 22:36:44 +0000164 const RegionStoreFeatures Features;
Zhongxing Xu17892752008-10-08 02:50:44 +0000165 RegionBindingsTy::Factory RBFactory;
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000166 RegionViews::Factory RVFactory;
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000167
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000168 const MemRegion* SelfRegion;
169 const ImplicitParamDecl *SelfDecl;
Zhongxing Xu17892752008-10-08 02:50:44 +0000170
171public:
Ted Kremenek9af46f52009-06-16 22:36:44 +0000172 RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
Ted Kremenek48ce7de2009-07-06 20:21:51 +0000173 : StoreManager(mgr, true),
Ted Kremenek9af46f52009-06-16 22:36:44 +0000174 Features(f),
Ted Kremenekd6cfbe42009-01-07 22:18:50 +0000175 RBFactory(mgr.getAllocator()),
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000176 RVFactory(mgr.getAllocator()),
Ted Kremenekc62abc12009-04-21 21:51:34 +0000177 SelfRegion(0), SelfDecl(0) {
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000178 if (const ObjCMethodDecl* MD =
179 dyn_cast<ObjCMethodDecl>(&StateMgr.getCodeDecl()))
180 SelfDecl = MD->getSelfDecl();
181 }
Zhongxing Xu17892752008-10-08 02:50:44 +0000182
183 virtual ~RegionStoreManager() {}
184
Ted Kremenek14453bf2009-03-03 19:02:42 +0000185 SubRegionMap* getSubRegionMap(const GRState *state);
Ted Kremenek59e8f112009-03-03 01:35:36 +0000186
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000187 /// getLValueString - Returns an SVal representing the lvalue of a
188 /// StringLiteral. Within RegionStore a StringLiteral has an
189 /// associated StringRegion, and the lvalue of a StringLiteral is
190 /// the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000191 SVal getLValueString(const GRState *state, const StringLiteral* S);
Zhongxing Xu143bf822008-10-25 14:18:57 +0000192
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000193 /// getLValueCompoundLiteral - Returns an SVal representing the
194 /// lvalue of a compound literal. Within RegionStore a compound
195 /// literal has an associated region, and the lvalue of the
196 /// compound literal is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000197 SVal getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr*);
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000198
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000199 /// getLValueVar - Returns an SVal that represents the lvalue of a
200 /// variable. Within RegionStore a variable has an associated
201 /// VarRegion, and the lvalue of the variable is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000202 SVal getLValueVar(const GRState *state, const VarDecl* VD);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000203
Ted Kremenek67f28532009-06-17 22:02:04 +0000204 SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000205
Ted Kremenek67f28532009-06-17 22:02:04 +0000206 SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D);
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000207
Ted Kremenek67f28532009-06-17 22:02:04 +0000208 SVal getLValueFieldOrIvar(const GRState *state, SVal Base, const Decl* D);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000209
Ted Kremenek67f28532009-06-17 22:02:04 +0000210 SVal getLValueElement(const GRState *state, QualType elementType,
Ted Kremenekf936f452009-05-04 06:18:28 +0000211 SVal Base, SVal Offset);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000212
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000213
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000214 /// ArrayToPointer - Emulates the "decay" of an array to a pointer
215 /// type. 'Array' represents the lvalue of the array being decayed
216 /// to a pointer, and the returned SVal represents the decayed
217 /// version of that lvalue (i.e., a pointer to the first element of
218 /// the array). This is called by GRExprEngine when evaluating
219 /// casts from arrays to pointers.
Zhongxing Xuf1d537f2009-03-30 05:55:46 +0000220 SVal ArrayToPointer(Loc Array);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000221
Ted Kremenek53ba0b62009-06-24 23:06:47 +0000222 SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,Loc L,
Ted Kremenek5c734622009-06-26 00:41:43 +0000223 NonLoc R, QualType resultTy);
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000224
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000225 Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); }
Ted Kremenek9deb0e32008-10-24 20:32:16 +0000226
227 /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
228 /// 'this' object (C++). When used when analyzing a normal function this
229 /// method returns NULL.
230 const MemRegion* getSelfRegion(Store) {
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000231 if (!SelfDecl)
232 return 0;
233
234 if (!SelfRegion) {
235 const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(&StateMgr.getCodeDecl());
236 SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
237 MRMgr.getHeapRegion());
238 }
239
240 return SelfRegion;
Ted Kremenek9deb0e32008-10-24 20:32:16 +0000241 }
Ted Kremenek67f28532009-06-17 22:02:04 +0000242
243 //===-------------------------------------------------------------------===//
244 // Binding values to regions.
245 //===-------------------------------------------------------------------===//
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000246
Ted Kremenek67f28532009-06-17 22:02:04 +0000247 const GRState *Bind(const GRState *state, Loc LV, SVal V);
248
249 const GRState *BindCompoundLiteral(const GRState *state,
250 const CompoundLiteralExpr* CL, SVal V);
251
252 const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal);
253
254 const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
255 return state;
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000256 }
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000257
Ted Kremenek67f28532009-06-17 22:02:04 +0000258 /// BindStruct - Bind a compound value to a structure.
259 const GRState *BindStruct(const GRState *, const TypedRegion* R, SVal V);
260
261 const GRState *BindArray(const GRState *state, const TypedRegion* R, SVal V);
262
263 /// KillStruct - Set the entire struct to unknown.
264 const GRState *KillStruct(const GRState *state, const TypedRegion* R);
265
266 const GRState *setDefaultValue(const GRState *state, const MemRegion* R, SVal V);
267
268 Store Remove(Store store, Loc LV);
269
270 //===------------------------------------------------------------------===//
271 // Loading values from regions.
272 //===------------------------------------------------------------------===//
273
274 /// The high level logic for this method is this:
275 /// Retrieve (L)
276 /// if L has binding
277 /// return L's binding
278 /// else if L is in killset
279 /// return unknown
280 /// else
281 /// if L is on stack or heap
282 /// return undefined
283 /// else
284 /// return symbolic
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000285 SValuator::CastResult Retrieve(const GRState *state, Loc L,
286 QualType T = QualType());
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000287
Ted Kremenek5bd2fe32009-07-15 06:09:28 +0000288 SVal RetrieveElement(const GRState *state, const ElementRegion *R);
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000289
Ted Kremenek5bd2fe32009-07-15 06:09:28 +0000290 SVal RetrieveField(const GRState *state, const FieldRegion *R);
291
292 SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
Ted Kremenek25c54572009-07-20 22:58:02 +0000293
Ted Kremenek9031dd72009-07-21 00:12:07 +0000294 SVal RetrieveVar(const GRState *state, const VarRegion *R);
295
Ted Kremenek25c54572009-07-20 22:58:02 +0000296 SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
297
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000298 SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
299 const TypedRegion *R, QualType castTy);
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000300
Ted Kremenek67f28532009-06-17 22:02:04 +0000301 /// Retrieve the values in a struct and return a CompoundVal, used when doing
302 /// struct copy:
303 /// struct s x, y;
304 /// x = y;
305 /// y's value is retrieved by this method.
306 SVal RetrieveStruct(const GRState *St, const TypedRegion* R);
307
308 SVal RetrieveArray(const GRState *St, const TypedRegion* R);
309
310 //===------------------------------------------------------------------===//
311 // State pruning.
312 //===------------------------------------------------------------------===//
313
314 /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values.
315 /// It returns a new Store with these values removed.
316 Store RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper,
317 llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
318
319 //===------------------------------------------------------------------===//
320 // Region "extents".
321 //===------------------------------------------------------------------===//
322
323 const GRState *setExtent(const GRState *state, const MemRegion* R, SVal Extent);
324 SVal getSizeInElements(const GRState *state, const MemRegion* R);
325
326 //===------------------------------------------------------------------===//
327 // Region "views".
328 //===------------------------------------------------------------------===//
329
330 const GRState *AddRegionView(const GRState *state, const MemRegion* View,
331 const MemRegion* Base);
332
333 const GRState *RemoveRegionView(const GRState *state, const MemRegion* View,
334 const MemRegion* Base);
335
336 //===------------------------------------------------------------------===//
337 // Utility methods.
338 //===------------------------------------------------------------------===//
339
Ted Kremenek48ce7de2009-07-06 20:21:51 +0000340 const GRState *setCastType(const GRState *state, const MemRegion* R,
341 QualType T);
Zhongxing Xubaf03a72008-11-24 09:44:56 +0000342
Zhongxing Xu82037252009-07-14 01:12:46 +0000343 const QualType *getCastType(const GRState *state, const MemRegion *R) {
344 return state->get<RegionCasts>(R);
345 }
346
Zhongxing Xu17892752008-10-08 02:50:44 +0000347 static inline RegionBindingsTy GetRegionBindings(Store store) {
Zhongxing Xu9c9ca082008-12-16 02:36:30 +0000348 return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
Zhongxing Xu17892752008-10-08 02:50:44 +0000349 }
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000350
Ted Kremenek53ba0b62009-06-24 23:06:47 +0000351 void print(Store store, llvm::raw_ostream& Out, const char* nl,
352 const char *sep);
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000353
354 void iterBindings(Store store, BindingsHandler& f) {
355 // FIXME: Implement.
356 }
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +0000357
Ted Kremenek67f28532009-06-17 22:02:04 +0000358 // FIXME: Remove.
359 BasicValueFactory& getBasicVals() {
360 return StateMgr.getBasicVals();
361 }
362
363 // FIXME: Remove.
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +0000364 ASTContext& getContext() { return StateMgr.getContext(); }
Zhongxing Xu17892752008-10-08 02:50:44 +0000365};
366
367} // end anonymous namespace
368
Zhongxing Xu82037252009-07-14 01:12:46 +0000369static bool isGenericPtr(ASTContext &Ctx, QualType Ty) {
370 if (Ty->isObjCIdType() || Ty->isObjCQualifiedIdType())
371 return true;
372
373 while (true) {
374 Ty = Ctx.getCanonicalType(Ty);
375
376 if (Ty->isVoidType())
377 return true;
378
Ted Kremenek35366a62009-07-17 17:50:17 +0000379 if (const PointerType *PT = Ty->getAsPointerType()) {
Zhongxing Xu82037252009-07-14 01:12:46 +0000380 Ty = PT->getPointeeType();
381 continue;
382 }
383
384 break;
385 }
386
387 return false;
388}
389
Ted Kremenek9af46f52009-06-16 22:36:44 +0000390//===----------------------------------------------------------------------===//
391// RegionStore creation.
392//===----------------------------------------------------------------------===//
393
394StoreManager *clang::CreateRegionStoreManager(GRStateManager& StMgr) {
395 RegionStoreFeatures F = maximal_features_tag();
396 return new RegionStoreManager(StMgr, F);
397}
398
399StoreManager *clang::CreateFieldsOnlyRegionStoreManager(GRStateManager &StMgr) {
400 RegionStoreFeatures F = minimal_features_tag();
401 F.enableFields(true);
402 return new RegionStoreManager(StMgr, F);
Ted Kremenek95c7b002008-10-24 01:04:59 +0000403}
404
Ted Kremenek14453bf2009-03-03 19:02:42 +0000405SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) {
Ted Kremenek59e8f112009-03-03 01:35:36 +0000406 RegionBindingsTy B = GetRegionBindings(state->getStore());
407 RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
408
409 for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
410 if (const SubRegion* R = dyn_cast<SubRegion>(I.getKey()))
411 M->add(R->getSuperRegion(), R);
412 }
413
Ted Kremenek14453bf2009-03-03 19:02:42 +0000414 return M;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000415}
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000416
Ted Kremenek9af46f52009-06-16 22:36:44 +0000417//===----------------------------------------------------------------------===//
418// getLValueXXX methods.
419//===----------------------------------------------------------------------===//
420
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000421/// getLValueString - Returns an SVal representing the lvalue of a
422/// StringLiteral. Within RegionStore a StringLiteral has an
423/// associated StringRegion, and the lvalue of a StringLiteral is the
424/// lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000425SVal RegionStoreManager::getLValueString(const GRState *St,
Zhongxing Xu143bf822008-10-25 14:18:57 +0000426 const StringLiteral* S) {
427 return loc::MemRegionVal(MRMgr.getStringRegion(S));
428}
429
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000430/// getLValueVar - Returns an SVal that represents the lvalue of a
431/// variable. Within RegionStore a variable has an associated
432/// VarRegion, and the lvalue of the variable is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000433SVal RegionStoreManager::getLValueVar(const GRState *St, const VarDecl* VD) {
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000434 return loc::MemRegionVal(MRMgr.getVarRegion(VD));
435}
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000436
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000437/// getLValueCompoundLiteral - Returns an SVal representing the lvalue
438/// of a compound literal. Within RegionStore a compound literal
439/// has an associated region, and the lvalue of the compound literal
440/// is the lvalue of that region.
441SVal
Ted Kremenek67f28532009-06-17 22:02:04 +0000442RegionStoreManager::getLValueCompoundLiteral(const GRState *St,
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000443 const CompoundLiteralExpr* CL) {
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000444 return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL));
445}
446
Ted Kremenek67f28532009-06-17 22:02:04 +0000447SVal RegionStoreManager::getLValueIvar(const GRState *St, const ObjCIvarDecl* D,
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000448 SVal Base) {
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000449 return getLValueFieldOrIvar(St, Base, D);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000450}
451
Ted Kremenek67f28532009-06-17 22:02:04 +0000452SVal RegionStoreManager::getLValueField(const GRState *St, SVal Base,
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000453 const FieldDecl* D) {
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000454 return getLValueFieldOrIvar(St, Base, D);
455}
456
Ted Kremenek67f28532009-06-17 22:02:04 +0000457SVal RegionStoreManager::getLValueFieldOrIvar(const GRState *St, SVal Base,
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000458 const Decl* D) {
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000459 if (Base.isUnknownOrUndef())
460 return Base;
461
462 Loc BaseL = cast<Loc>(Base);
463 const MemRegion* BaseR = 0;
464
465 switch (BaseL.getSubKind()) {
466 case loc::MemRegionKind:
467 BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
468 break;
469
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000470 case loc::GotoLabelKind:
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000471 // These are anormal cases. Flag an undefined value.
472 return UndefinedVal();
473
474 case loc::ConcreteIntKind:
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000475 // While these seem funny, this can happen through casts.
476 // FIXME: What we should return is the field offset. For example,
477 // add the field offset to the integer value. That way funny things
478 // like this work properly: &(((struct foo *) 0xa)->f)
479 return Base;
480
481 default:
Zhongxing Xu13d1ee22008-11-07 08:57:30 +0000482 assert(0 && "Unhandled Base.");
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000483 return Base;
484 }
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000485
486 // NOTE: We must have this check first because ObjCIvarDecl is a subclass
487 // of FieldDecl.
488 if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D))
489 return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000490
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000491 return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000492}
493
Ted Kremenek67f28532009-06-17 22:02:04 +0000494SVal RegionStoreManager::getLValueElement(const GRState *St,
Ted Kremenekf936f452009-05-04 06:18:28 +0000495 QualType elementType,
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000496 SVal Base, SVal Offset) {
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000497
Ted Kremenekde7ec632009-03-09 22:44:49 +0000498 // If the base is an unknown or undefined value, just return it back.
499 // FIXME: For absolute pointer addresses, we just return that value back as
500 // well, although in reality we should return the offset added to that
501 // value.
502 if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
Zhongxing Xu4a1513e2008-10-27 12:23:17 +0000503 return Base;
504
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000505 // Only handle integer offsets... for now.
506 if (!isa<nonloc::ConcreteInt>(Offset))
Zhongxing Xue4d13932008-11-13 09:48:44 +0000507 return UnknownVal();
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000508
Zhongxing Xuce760782009-05-09 13:20:07 +0000509 const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000510
511 // Pointer of any type can be cast and used as array base.
512 const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
513
Ted Kremenek46537392009-07-16 01:33:37 +0000514 // Convert the offset to the appropriate size and signedness.
515 Offset = ValMgr.convertToArrayIndex(Offset);
516
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000517 if (!ElemR) {
518 //
519 // If the base region is not an ElementRegion, create one.
520 // This can happen in the following example:
521 //
522 // char *p = __builtin_alloc(10);
523 // p[1] = 8;
524 //
Zhongxing Xuce760782009-05-09 13:20:07 +0000525 // Observe that 'p' binds to an AllocaRegion.
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000526 //
Ted Kremenekf936f452009-05-04 06:18:28 +0000527 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000528 BaseRegion, getContext()));
Zhongxing Xue4d13932008-11-13 09:48:44 +0000529 }
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000530
531 SVal BaseIdx = ElemR->getIndex();
532
533 if (!isa<nonloc::ConcreteInt>(BaseIdx))
534 return UnknownVal();
535
536 const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
537 const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
538 assert(BaseIdxI.isSigned());
539
Ted Kremenek46537392009-07-16 01:33:37 +0000540 // Compute the new index.
541 SVal NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI));
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000542
Ted Kremenek46537392009-07-16 01:33:37 +0000543 // Construct the new ElementRegion.
544 const MemRegion *ArrayR = ElemR->getSuperRegion();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000545 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
546 getContext()));
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000547}
548
Ted Kremenek9af46f52009-06-16 22:36:44 +0000549//===----------------------------------------------------------------------===//
550// Extents for regions.
551//===----------------------------------------------------------------------===//
552
Ted Kremenek67f28532009-06-17 22:02:04 +0000553SVal RegionStoreManager::getSizeInElements(const GRState *state,
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000554 const MemRegion *R) {
555
556 switch (R->getKind()) {
557 case MemRegion::MemSpaceRegionKind:
558 assert(0 && "Cannot index into a MemSpace");
559 return UnknownVal();
560
561 case MemRegion::CodeTextRegionKind:
562 // Technically this can happen if people do funny things with casts.
Ted Kremenek14553ab2009-01-30 00:08:43 +0000563 return UnknownVal();
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000564
565 // Not yet handled.
566 case MemRegion::AllocaRegionKind:
567 case MemRegion::CompoundLiteralRegionKind:
568 case MemRegion::ElementRegionKind:
569 case MemRegion::FieldRegionKind:
570 case MemRegion::ObjCIvarRegionKind:
571 case MemRegion::ObjCObjectRegionKind:
572 case MemRegion::SymbolicRegionKind:
573 return UnknownVal();
574
575 case MemRegion::StringRegionKind: {
576 const StringLiteral* Str = cast<StringRegion>(R)->getStringLiteral();
577 // We intentionally made the size value signed because it participates in
578 // operations with signed indices.
579 return ValMgr.makeIntVal(Str->getByteLength()+1, false);
Ted Kremenek14553ab2009-01-30 00:08:43 +0000580 }
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000581
582 // TypedViewRegion will soon be removed.
583 case MemRegion::TypedViewRegionKind:
584 return UnknownVal();
Zhongxing Xu20794942009-05-06 08:33:50 +0000585
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000586 case MemRegion::VarRegionKind: {
587 const VarRegion* VR = cast<VarRegion>(R);
588 // Get the type of the variable.
589 QualType T = VR->getDesugaredValueType(getContext());
590
591 // FIXME: Handle variable-length arrays.
592 if (isa<VariableArrayType>(T))
593 return UnknownVal();
594
595 if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
596 // return the size as signed integer.
597 return ValMgr.makeIntVal(CAT->getSize(), false);
598 }
599
600 const QualType* CastTy = state->get<RegionCasts>(VR);
601
602 // If the VarRegion is cast to other type, compute the size with respect to
603 // that type.
604 if (CastTy) {
605 QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
606 QualType VarTy = VR->getValueType(getContext());
607 uint64_t EleSize = getContext().getTypeSize(EleTy);
608 uint64_t VarSize = getContext().getTypeSize(VarTy);
609 assert(VarSize != 0);
610 return ValMgr.makeIntVal(VarSize/EleSize, false);
611 }
612
613 // Clients can use ordinary variables as if they were arrays. These
614 // essentially are arrays of size 1.
615 return ValMgr.makeIntVal(1, false);
Zhongxing Xu41fd0182009-05-06 11:51:48 +0000616 }
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000617
618 case MemRegion::BEG_DECL_REGIONS:
619 case MemRegion::END_DECL_REGIONS:
620 case MemRegion::BEG_TYPED_REGIONS:
621 case MemRegion::END_TYPED_REGIONS:
622 assert(0 && "Infeasible region");
623 return UnknownVal();
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000624 }
Ted Kremenek7ecbfbc2009-07-10 22:30:06 +0000625
626 assert(0 && "Unreachable");
Ted Kremeneka21362d2009-01-06 19:12:06 +0000627 return UnknownVal();
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000628}
629
Ted Kremenek67f28532009-06-17 22:02:04 +0000630const GRState *RegionStoreManager::setExtent(const GRState *state,
631 const MemRegion *region,
632 SVal extent) {
633 return state->set<RegionExtents>(region, extent);
Ted Kremenek9af46f52009-06-16 22:36:44 +0000634}
635
636//===----------------------------------------------------------------------===//
637// Location and region casting.
638//===----------------------------------------------------------------------===//
639
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000640/// ArrayToPointer - Emulates the "decay" of an array to a pointer
641/// type. 'Array' represents the lvalue of the array being decayed
642/// to a pointer, and the returned SVal represents the decayed
643/// version of that lvalue (i.e., a pointer to the first element of
644/// the array). This is called by GRExprEngine when evaluating casts
645/// from arrays to pointers.
Zhongxing Xuf1d537f2009-03-30 05:55:46 +0000646SVal RegionStoreManager::ArrayToPointer(Loc Array) {
Ted Kremenekabb042f2008-12-13 19:24:37 +0000647 if (!isa<loc::MemRegionVal>(Array))
648 return UnknownVal();
649
650 const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
651 const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R);
652
Ted Kremenekbbee1a72009-01-13 01:03:27 +0000653 if (!ArrayR)
Ted Kremenekabb042f2008-12-13 19:24:37 +0000654 return UnknownVal();
655
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000656 // Strip off typedefs from the ArrayRegion's ValueType.
657 QualType T = ArrayR->getValueType(getContext())->getDesugaredType();
Ted Kremenekf936f452009-05-04 06:18:28 +0000658 ArrayType *AT = cast<ArrayType>(T);
659 T = AT->getElementType();
660
Ted Kremenek75185b52009-07-16 00:00:11 +0000661 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
662 ElementRegion* ER = MRMgr.getElementRegion(T, ZeroIdx, ArrayR, getContext());
Zhongxing Xu0b7e6422008-10-26 02:23:57 +0000663
664 return loc::MemRegionVal(ER);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000665}
666
Ted Kremenek9af46f52009-06-16 22:36:44 +0000667//===----------------------------------------------------------------------===//
668// Pointer arithmetic.
669//===----------------------------------------------------------------------===//
670
Zhongxing Xu262fd032009-05-20 09:00:16 +0000671SVal RegionStoreManager::EvalBinOp(const GRState *state,
Ted Kremenek5c734622009-06-26 00:41:43 +0000672 BinaryOperator::Opcode Op, Loc L, NonLoc R,
673 QualType resultTy) {
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000674 // Assume the base location is MemRegionVal.
Ted Kremenek5dc27462009-03-03 02:51:43 +0000675 if (!isa<loc::MemRegionVal>(L))
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000676 return UnknownVal();
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000677
Zhongxing Xua1718c72009-04-03 07:33:13 +0000678 const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000679 const ElementRegion *ER = 0;
Zhongxing Xu262fd032009-05-20 09:00:16 +0000680
Ted Kremenek3bccf082009-07-11 00:58:27 +0000681 switch (MR->getKind()) {
682 case MemRegion::SymbolicRegionKind: {
683 const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
684 QualType T;
Ted Kremenek356e9d62009-07-22 04:35:42 +0000685#if USE_REGION_CASTS
Ted Kremenek3bccf082009-07-11 00:58:27 +0000686 // If the SymbolicRegion was cast to another type, use that type.
687 if (const QualType *t = state->get<RegionCasts>(SR))
688 T = *t;
Ted Kremenek356e9d62009-07-22 04:35:42 +0000689 else
690#endif
691 {
Ted Kremenek3bccf082009-07-11 00:58:27 +0000692 // Otherwise use the symbol's type.
693 SymbolRef Sym = SR->getSymbol();
694 T = Sym->getType(getContext());
695 }
696
Ted Kremenek35366a62009-07-17 17:50:17 +0000697 QualType EleTy = T->getAsPointerType()->getPointeeType();
Ted Kremenek3bccf082009-07-11 00:58:27 +0000698 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
699 ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
700 break;
Zhongxing Xu005f07b2009-06-19 04:51:14 +0000701 }
Ted Kremenek3bccf082009-07-11 00:58:27 +0000702 case MemRegion::AllocaRegionKind: {
703 // Get the alloca region's current cast type.
704 const AllocaRegion *AR = cast<AllocaRegion>(MR);
705 QualType T = *(state->get<RegionCasts>(AR));
Ted Kremenek35366a62009-07-17 17:50:17 +0000706 QualType EleTy = T->getAsPointerType()->getPointeeType();
Ted Kremenek3bccf082009-07-11 00:58:27 +0000707 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
708 ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
709 break;
710 }
Zhongxing Xua1718c72009-04-03 07:33:13 +0000711
Ted Kremenek3bccf082009-07-11 00:58:27 +0000712 case MemRegion::ElementRegionKind: {
713 ER = cast<ElementRegion>(MR);
714 break;
715 }
716
717 // Not yet handled.
718 case MemRegion::VarRegionKind:
719 case MemRegion::StringRegionKind:
720 case MemRegion::CompoundLiteralRegionKind:
721 case MemRegion::FieldRegionKind:
722 case MemRegion::ObjCObjectRegionKind:
723 case MemRegion::ObjCIvarRegionKind:
724 return UnknownVal();
725
726 // TypedViewRegion will soon be removed.
727 case MemRegion::TypedViewRegionKind:
728 return UnknownVal();
729
730 case MemRegion::CodeTextRegionKind:
731 // Technically this can happen if people do funny things with casts.
732 return UnknownVal();
733
734 case MemRegion::MemSpaceRegionKind:
735 assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
736 return UnknownVal();
737
738 case MemRegion::BEG_DECL_REGIONS:
739 case MemRegion::END_DECL_REGIONS:
740 case MemRegion::BEG_TYPED_REGIONS:
741 case MemRegion::END_TYPED_REGIONS:
742 assert(0 && "Infeasible region");
743 return UnknownVal();
Zhongxing Xu5414a5c2009-06-21 13:24:24 +0000744 }
Zhongxing Xu2b1dc172009-03-11 07:43:49 +0000745
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000746 SVal Idx = ER->getIndex();
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000747 nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
748 nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R);
749
750 // Only support concrete integer indexes for now.
751 if (Base && Offset) {
Ted Kremenek46537392009-07-16 01:33:37 +0000752 // FIXME: Should use SValuator here.
753 SVal NewIdx = Base->evalBinOp(ValMgr, Op,
754 cast<nonloc::ConcreteInt>(ValMgr.convertToArrayIndex(*Offset)));
Ted Kremenekf936f452009-05-04 06:18:28 +0000755 const MemRegion* NewER =
Ted Kremenek46537392009-07-16 01:33:37 +0000756 MRMgr.getElementRegion(ER->getElementType(), NewIdx, ER->getSuperRegion(),
757 getContext());
Zhongxing Xud91ee272009-06-23 09:02:15 +0000758 return ValMgr.makeLoc(NewER);
Ted Kremenek5dc27462009-03-03 02:51:43 +0000759 }
760
761 return UnknownVal();
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000762}
763
Ted Kremenek9af46f52009-06-16 22:36:44 +0000764//===----------------------------------------------------------------------===//
765// Loading values from regions.
766//===----------------------------------------------------------------------===//
767
Ted Kremeneka6275a52009-07-15 02:31:43 +0000768static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) {
769 RTy = Ctx.getCanonicalType(RTy);
770 UsedTy = Ctx.getCanonicalType(UsedTy);
771
772 if (RTy == UsedTy)
773 return false;
774
Ted Kremenek25c54572009-07-20 22:58:02 +0000775
776 // Recursively check the types. We basically want to see if a pointer value
777 // is ever reinterpreted as a non-pointer, e.g. void** and intptr_t*
778 // represents a reinterpretation.
779 if (Loc::IsLocType(RTy) && Loc::IsLocType(UsedTy)) {
780 const PointerType *PRTy = RTy->getAsPointerType();
781 const PointerType *PUsedTy = UsedTy->getAsPointerType();
782
783 return PUsedTy && PRTy &&
784 IsReinterpreted(PRTy->getPointeeType(),
785 PUsedTy->getPointeeType(), Ctx);
786 }
787
788 return true;
Ted Kremeneka6275a52009-07-15 02:31:43 +0000789}
790
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000791SValuator::CastResult
792RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
Ted Kremenek67f28532009-06-17 22:02:04 +0000793
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000794 assert(!isa<UnknownVal>(L) && "location unknown");
795 assert(!isa<UndefinedVal>(L) && "location undefined");
796
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000797 // FIXME: Is this even possible? Shouldn't this be treated as a null
798 // dereference at a higher level?
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000799 if (isa<loc::ConcreteInt>(L))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000800 return SValuator::CastResult(state, UndefinedVal());
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000801
Ted Kremenek67f28532009-06-17 22:02:04 +0000802 const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
Zhongxing Xua1718c72009-04-03 07:33:13 +0000803
Zhongxing Xu91844122009-05-20 09:18:48 +0000804 // FIXME: return symbolic value for these cases.
Zhongxing Xua1718c72009-04-03 07:33:13 +0000805 // Example:
806 // void f(int* p) { int x = *p; }
Zhongxing Xu91844122009-05-20 09:18:48 +0000807 // char* p = alloca();
808 // read(p);
809 // c = *p;
Ted Kremenek60fbe8f2009-07-14 20:48:22 +0000810 if (isa<AllocaRegion>(MR))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000811 return SValuator::CastResult(state, UnknownVal());
Ted Kremenek60fbe8f2009-07-14 20:48:22 +0000812
813 if (isa<SymbolicRegion>(MR)) {
814 ASTContext &Ctx = getContext();
Zhongxing Xud79bf552009-07-15 05:09:24 +0000815 SVal idx = ValMgr.makeZeroArrayIndex();
Ted Kremeneka6275a52009-07-15 02:31:43 +0000816 assert(!T.isNull());
Ted Kremenek60fbe8f2009-07-14 20:48:22 +0000817 MR = MRMgr.getElementRegion(T, idx, MR, Ctx);
818 }
819
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000820 // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
821 // instead of 'Loc', and have the other Loc cases handled at a higher level.
Ted Kremenek67f28532009-06-17 22:02:04 +0000822 const TypedRegion *R = cast<TypedRegion>(MR);
Ted Kremeneka6275a52009-07-15 02:31:43 +0000823 QualType RTy = R->getValueType(getContext());
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000824
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000825 // FIXME: We should eventually handle funny addressing. e.g.:
826 //
827 // int x = ...;
828 // int *p = &x;
829 // char *q = (char*) p;
830 // char c = *q; // returns the first byte of 'x'.
831 //
832 // Such funny addressing will occur due to layering of regions.
833
Ted Kremeneka6275a52009-07-15 02:31:43 +0000834 ASTContext &Ctx = getContext();
835 if (!T.isNull() && IsReinterpreted(RTy, T, Ctx)) {
Ted Kremenek46537392009-07-16 01:33:37 +0000836 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
837 R = MRMgr.getElementRegion(T, ZeroIdx, R, Ctx);
Ted Kremeneka6275a52009-07-15 02:31:43 +0000838 RTy = T;
Ted Kremenek41fb0df2009-07-15 04:23:32 +0000839 assert(Ctx.getCanonicalType(RTy) ==
840 Ctx.getCanonicalType(R->getValueType(Ctx)));
Ted Kremeneka6275a52009-07-15 02:31:43 +0000841 }
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000842
Zhongxing Xu1038f9f2009-03-09 09:15:51 +0000843 if (RTy->isStructureType())
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000844 return SValuator::CastResult(state, RetrieveStruct(state, R));
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000845
846 if (RTy->isArrayType())
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000847 return SValuator::CastResult(state, RetrieveArray(state, R));
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000848
Zhongxing Xu1038f9f2009-03-09 09:15:51 +0000849 // FIXME: handle Vector types.
850 if (RTy->isVectorType())
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000851 return SValuator::CastResult(state, UnknownVal());
Zhongxing Xu99c20302009-06-28 14:16:39 +0000852
853 if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000854 return CastRetrievedVal(RetrieveField(state, FR), state, FR, T);
Zhongxing Xu99c20302009-06-28 14:16:39 +0000855
856 if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000857 return CastRetrievedVal(RetrieveElement(state, ER), state, ER, T);
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000858
Ted Kremenek25c54572009-07-20 22:58:02 +0000859 if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000860 return CastRetrievedVal(RetrieveObjCIvar(state, IVR), state, IVR, T);
Ted Kremenek9031dd72009-07-21 00:12:07 +0000861
862 if (const VarRegion *VR = dyn_cast<VarRegion>(R))
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000863 return CastRetrievedVal(RetrieveVar(state, VR), state, VR, T);
Ted Kremenek25c54572009-07-20 22:58:02 +0000864
Ted Kremenek67f28532009-06-17 22:02:04 +0000865 RegionBindingsTy B = GetRegionBindings(state->getStore());
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000866 RegionBindingsTy::data_type* V = B.lookup(R);
867
868 // Check if the region has a binding.
869 if (V)
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000870 return SValuator::CastResult(state, *V);
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000871
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000872 // The location does not have a bound value. This means that it has
873 // the value it had upon its creation and/or entry to the analyzed
874 // function/method. These are either symbolic values or 'undefined'.
875
Ted Kremenek356e9d62009-07-22 04:35:42 +0000876#if HEAP_UNDEFINED
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000877 if (R->hasHeapOrStackStorage()) {
Ted Kremenek356e9d62009-07-22 04:35:42 +0000878#else
879 if (R->hasStackStorage()) {
880#endif
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000881 // All stack variables are considered to have undefined values
882 // upon creation. All heap allocated blocks are considered to
883 // have undefined values as well unless they are explicitly bound
884 // to specific values.
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000885 return SValuator::CastResult(state, UndefinedVal());
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000886 }
887
Ted Kremenek356e9d62009-07-22 04:35:42 +0000888#if USE_REGION_CASTS
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000889 // If the region is already cast to another type, use that type to create the
890 // symbol value.
891 if (const QualType *p = state->get<RegionCasts>(R)) {
892 QualType T = *p;
Ted Kremenek35366a62009-07-17 17:50:17 +0000893 RTy = T->getAsPointerType()->getPointeeType();
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000894 }
Ted Kremenek356e9d62009-07-22 04:35:42 +0000895#endif
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000896
Ted Kremenekbb2b4332009-07-02 22:16:42 +0000897 // All other values are symbolic.
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000898 return SValuator::CastResult(state,
899 ValMgr.getRegionValueSymbolValOrUnknown(R, RTy));
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000900}
901
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000902SVal RegionStoreManager::RetrieveElement(const GRState* state,
903 const ElementRegion* R) {
904 // Check if the region has a binding.
905 RegionBindingsTy B = GetRegionBindings(state->getStore());
Ted Kremenek921109a2009-07-01 23:19:52 +0000906 if (const SVal* V = B.lookup(R))
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000907 return *V;
908
Ted Kremenek921109a2009-07-01 23:19:52 +0000909 const MemRegion* superR = R->getSuperRegion();
910
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000911 // Check if the region is an element region of a string literal.
Ted Kremenek921109a2009-07-01 23:19:52 +0000912 if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000913 const StringLiteral *Str = StrR->getStringLiteral();
914 SVal Idx = R->getIndex();
915 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
916 int64_t i = CI->getValue().getSExtValue();
917 char c;
918 if (i == Str->getByteLength())
919 c = '\0';
920 else
921 c = Str->getStrData()[i];
922 return ValMgr.makeIntVal(c, getContext().CharTy);
923 }
924 }
925
Zhongxing Xu7abe0192009-06-30 12:32:59 +0000926 // Check if the super region has a default value.
Ted Kremenek921109a2009-07-01 23:19:52 +0000927 if (const SVal *D = state->get<RegionDefaultValue>(superR)) {
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000928 if (D->hasConjuredSymbol())
929 return ValMgr.getRegionValueSymbolVal(R);
930 else
931 return *D;
932 }
933
Zhongxing Xu7abe0192009-06-30 12:32:59 +0000934 // Check if the super region has a binding.
Ted Kremeneka6275a52009-07-15 02:31:43 +0000935 if (const SVal *V = B.lookup(superR)) {
936 if (SymbolRef parentSym = V->getAsSymbol())
937 return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
Ted Kremenek356e9d62009-07-22 04:35:42 +0000938
939 if (V->isUnknownOrUndef())
940 return *V;
Ted Kremeneka6275a52009-07-15 02:31:43 +0000941
942 // Other cases: give up.
Zhongxing Xu8834af32009-07-03 06:11:41 +0000943 return UnknownVal();
Zhongxing Xu7abe0192009-06-30 12:32:59 +0000944 }
Ted Kremenek921109a2009-07-01 23:19:52 +0000945
Ted Kremenek356e9d62009-07-22 04:35:42 +0000946#if 0
Ted Kremenek921109a2009-07-01 23:19:52 +0000947 if (R->hasHeapStorage()) {
Ted Kremenek356e9d62009-07-22 04:35:42 +0000948 // FIXME: If the region has heap storage and we know nothing special
949 // about its bindings, should we instead return UnknownVal? Seems like
950 // we should only return UndefinedVal in the cases where we know the value
951 // will be undefined.
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000952 return UndefinedVal();
Ted Kremenek921109a2009-07-01 23:19:52 +0000953 }
Ted Kremenek356e9d62009-07-22 04:35:42 +0000954#endif
955
Ted Kremenekdc147262009-07-02 22:02:15 +0000956 if (R->hasStackStorage() && !R->hasParametersStorage()) {
Ted Kremenek921109a2009-07-01 23:19:52 +0000957 // Currently we don't reason specially about Clang-style vectors. Check
958 // if superR is a vector and if so return Unknown.
959 if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
960 if (typedSuperR->getValueType(getContext())->isVectorType())
961 return UnknownVal();
962 }
963
964 return UndefinedVal();
965 }
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000966
967 QualType Ty = R->getValueType(getContext());
968
Ted Kremenek356e9d62009-07-22 04:35:42 +0000969#if USE_REGION_CASTS
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000970 // If the region is already cast to another type, use that type to create the
971 // symbol value.
972 if (const QualType *p = state->get<RegionCasts>(R))
Ted Kremenek35366a62009-07-17 17:50:17 +0000973 Ty = (*p)->getAsPointerType()->getPointeeType();
Ted Kremenek356e9d62009-07-22 04:35:42 +0000974#endif
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000975
Ted Kremenekbb2b4332009-07-02 22:16:42 +0000976 return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000977}
978
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000979SVal RegionStoreManager::RetrieveField(const GRState* state,
980 const FieldRegion* R) {
981 QualType Ty = R->getValueType(getContext());
982
983 // Check if the region has a binding.
984 RegionBindingsTy B = GetRegionBindings(state->getStore());
Ted Kremenek8b2ba312009-07-01 23:30:34 +0000985 if (const SVal* V = B.lookup(R))
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000986 return *V;
987
Ted Kremenek8b2ba312009-07-01 23:30:34 +0000988 const MemRegion* superR = R->getSuperRegion();
989 if (const SVal* D = state->get<RegionDefaultValue>(superR)) {
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000990 if (D->hasConjuredSymbol())
991 return ValMgr.getRegionValueSymbolVal(R);
992
993 if (D->isZeroConstant())
994 return ValMgr.makeZeroVal(Ty);
995
996 if (D->isUnknown())
997 return *D;
998
999 assert(0 && "Unknown default value");
1000 }
1001
Ted Kremenek356e9d62009-07-22 04:35:42 +00001002#if HEAP_UNDEFINED
Ted Kremenekdc147262009-07-02 22:02:15 +00001003 // FIXME: Is this correct? Should it be UnknownVal?
1004 if (R->hasHeapStorage())
1005 return UndefinedVal();
Ted Kremenek356e9d62009-07-22 04:35:42 +00001006#endif
Ted Kremenekdc147262009-07-02 22:02:15 +00001007
1008 if (R->hasStackStorage() && !R->hasParametersStorage())
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001009 return UndefinedVal();
1010
Ted Kremenek356e9d62009-07-22 04:35:42 +00001011#if USE_REGION_CASTS
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001012 // If the region is already cast to another type, use that type to create the
1013 // symbol value.
1014 if (const QualType *p = state->get<RegionCasts>(R)) {
1015 QualType tmp = *p;
Ted Kremenek35366a62009-07-17 17:50:17 +00001016 Ty = tmp->getAsPointerType()->getPointeeType();
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001017 }
Ted Kremenek356e9d62009-07-22 04:35:42 +00001018#endif
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001019
Ted Kremenekbb2b4332009-07-02 22:16:42 +00001020 // All other values are symbolic.
1021 return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001022}
1023
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001024SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state,
1025 const ObjCIvarRegion* R) {
1026
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001027 // Check if the region has a binding.
1028 RegionBindingsTy B = GetRegionBindings(state->getStore());
1029
1030 if (const SVal* V = B.lookup(R))
1031 return *V;
1032
1033 const MemRegion *superR = R->getSuperRegion();
1034
1035 // Check if the super region has a binding.
1036 if (const SVal *V = B.lookup(superR)) {
1037 if (SymbolRef parentSym = V->getAsSymbol())
1038 return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
1039
1040 // Other cases: give up.
1041 return UnknownVal();
1042 }
1043
Ted Kremenek25c54572009-07-20 22:58:02 +00001044 return RetrieveLazySymbol(state, R);
1045}
1046
Ted Kremenek9031dd72009-07-21 00:12:07 +00001047SVal RegionStoreManager::RetrieveVar(const GRState *state,
1048 const VarRegion *R) {
1049
1050 // Check if the region has a binding.
1051 RegionBindingsTy B = GetRegionBindings(state->getStore());
1052
1053 if (const SVal* V = B.lookup(R))
1054 return *V;
1055
1056 // Lazily derive a value for the VarRegion.
1057 const VarDecl *VD = R->getDecl();
1058
1059 if (VD == SelfDecl)
1060 return loc::MemRegionVal(getSelfRegion(0));
1061
1062 if (R->hasGlobalsOrParametersStorage())
1063 return ValMgr.getRegionValueSymbolValOrUnknown(R, VD->getType());
1064
1065 return UndefinedVal();
1066}
1067
Ted Kremenek25c54572009-07-20 22:58:02 +00001068SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state,
1069 const TypedRegion *R) {
1070
1071 QualType valTy = R->getValueType(getContext());
Ted Kremenek356e9d62009-07-22 04:35:42 +00001072
1073#if USE_REGION_CASTS
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001074 // If the region is already cast to another type, use that type to create the
1075 // symbol value.
Ted Kremenek25c54572009-07-20 22:58:02 +00001076 if (const QualType *ty = state->get<RegionCasts>(R)) {
1077 if (const PointerType *PT = (*ty)->getAsPointerType()) {
1078 QualType castTy = PT->getPointeeType();
1079
1080 if (!IsReinterpreted(valTy, castTy, getContext()))
1081 valTy = castTy;
1082 }
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001083 }
Ted Kremenek356e9d62009-07-22 04:35:42 +00001084#endif
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001085
1086 // All other values are symbolic.
Ted Kremenek25c54572009-07-20 22:58:02 +00001087 return ValMgr.getRegionValueSymbolValOrUnknown(R, valTy);
Ted Kremenek5bd2fe32009-07-15 06:09:28 +00001088}
1089
Zhongxing Xu88c675f2009-06-18 06:29:10 +00001090SVal RegionStoreManager::RetrieveStruct(const GRState *state,
1091 const TypedRegion* R){
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001092 QualType T = R->getValueType(getContext());
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001093 assert(T->isStructureType());
1094
Zhongxing Xub7507d12009-06-11 07:27:30 +00001095 const RecordType* RT = T->getAsStructureType();
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001096 RecordDecl* RD = RT->getDecl();
1097 assert(RD->isDefinition());
1098
1099 llvm::ImmutableList<SVal> StructVal = getBasicVals().getEmptySValList();
1100
Ted Kremenek67f28532009-06-17 22:02:04 +00001101 // FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
1102 // reverse iterator, we should implement one.
Argyrios Kyrtzidis17945a02009-06-30 02:36:12 +00001103 std::vector<FieldDecl *> Fields(RD->field_begin(), RD->field_end());
Douglas Gregor44b43212008-12-11 16:49:14 +00001104
Douglas Gregore267ff32008-12-11 20:41:00 +00001105 for (std::vector<FieldDecl *>::reverse_iterator Field = Fields.rbegin(),
1106 FieldEnd = Fields.rend();
1107 Field != FieldEnd; ++Field) {
1108 FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001109 QualType FTy = (*Field)->getType();
Ted Kremenek32c3fa42009-07-21 21:03:30 +00001110 SVal FieldValue = Retrieve(state, loc::MemRegionVal(FR), FTy).getSVal();
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001111 StructVal = getBasicVals().consVals(FieldValue, StructVal);
1112 }
1113
Zhongxing Xud91ee272009-06-23 09:02:15 +00001114 return ValMgr.makeCompoundVal(T, StructVal);
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001115}
1116
Ted Kremenek67f28532009-06-17 22:02:04 +00001117SVal RegionStoreManager::RetrieveArray(const GRState *state,
1118 const TypedRegion * R) {
1119
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001120 QualType T = R->getValueType(getContext());
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001121 ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
1122
1123 llvm::ImmutableList<SVal> ArrayVal = getBasicVals().getEmptySValList();
Ted Kremenek46537392009-07-16 01:33:37 +00001124 uint64_t size = CAT->getSize().getZExtValue();
1125 for (uint64_t i = 0; i < size; ++i) {
1126 SVal Idx = ValMgr.makeArrayIndex(i);
Zhongxing Xu143b2fc2009-06-16 09:55:50 +00001127 ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R,
1128 getContext());
Ted Kremenekf936f452009-05-04 06:18:28 +00001129 QualType ETy = ER->getElementType();
Ted Kremenek32c3fa42009-07-21 21:03:30 +00001130 SVal ElementVal = Retrieve(state, loc::MemRegionVal(ER), ETy).getSVal();
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001131 ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal);
1132 }
1133
Zhongxing Xud91ee272009-06-23 09:02:15 +00001134 return ValMgr.makeCompoundVal(T, ArrayVal);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001135}
1136
Ted Kremenek32c3fa42009-07-21 21:03:30 +00001137SValuator::CastResult RegionStoreManager::CastRetrievedVal(SVal V,
1138 const GRState *state,
1139 const TypedRegion *R,
1140 QualType castTy) {
Ted Kremenek9031dd72009-07-21 00:12:07 +00001141 if (castTy.isNull())
Ted Kremenek32c3fa42009-07-21 21:03:30 +00001142 return SValuator::CastResult(state, V);
Ted Kremenek9031dd72009-07-21 00:12:07 +00001143
1144 ASTContext &Ctx = getContext();
Ted Kremenek32c3fa42009-07-21 21:03:30 +00001145 return ValMgr.getSValuator().EvalCast(V, state, castTy, R->getValueType(Ctx));
Ted Kremenek25c54572009-07-20 22:58:02 +00001146}
1147
Ted Kremenek9af46f52009-06-16 22:36:44 +00001148//===----------------------------------------------------------------------===//
1149// Binding values to regions.
1150//===----------------------------------------------------------------------===//
Zhongxing Xu17892752008-10-08 02:50:44 +00001151
Zhongxing Xu9c9ca082008-12-16 02:36:30 +00001152Store RegionStoreManager::Remove(Store store, Loc L) {
Ted Kremenek0964a062009-01-21 06:57:53 +00001153 const MemRegion* R = 0;
1154
1155 if (isa<loc::MemRegionVal>(L))
1156 R = cast<loc::MemRegionVal>(L).getRegion();
Ted Kremenek0964a062009-01-21 06:57:53 +00001157
1158 if (R) {
1159 RegionBindingsTy B = GetRegionBindings(store);
1160 return RBFactory.Remove(B, R).getRoot();
1161 }
1162
1163 return store;
Zhongxing Xu9c9ca082008-12-16 02:36:30 +00001164}
1165
Ted Kremenek67f28532009-06-17 22:02:04 +00001166const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
Zhongxing Xu87453d12009-06-28 10:16:11 +00001167 if (isa<loc::ConcreteInt>(L))
1168 return state;
1169
Ted Kremenek9af46f52009-06-16 22:36:44 +00001170 // If we get here, the location should be a region.
1171 const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
Ted Kremenek9af46f52009-06-16 22:36:44 +00001172
1173 // Check if the region is a struct region.
1174 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
1175 if (TR->getValueType(getContext())->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001176 return BindStruct(state, TR, V);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001177
Ted Kremenek67f28532009-06-17 22:02:04 +00001178 RegionBindingsTy B = GetRegionBindings(state->getStore());
Ted Kremenek9af46f52009-06-16 22:36:44 +00001179
Zhongxing Xue4df9c42009-06-25 05:52:16 +00001180 B = RBFactory.Add(B, R, V);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001181
Ted Kremenek67f28532009-06-17 22:02:04 +00001182 return state->makeWithStore(B.getRoot());
Ted Kremenek9af46f52009-06-16 22:36:44 +00001183}
1184
Ted Kremenek67f28532009-06-17 22:02:04 +00001185const GRState *RegionStoreManager::BindDecl(const GRState *state,
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001186 const VarDecl* VD, SVal InitVal) {
Zhongxing Xua4f28ff2008-11-13 08:41:36 +00001187
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001188 QualType T = VD->getType();
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001189 VarRegion* VR = MRMgr.getVarRegion(VD);
Zhongxing Xuf0dfa8d2008-10-31 08:10:01 +00001190
Ted Kremenek0964a062009-01-21 06:57:53 +00001191 if (T->isArrayType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001192 return BindArray(state, VR, InitVal);
Ted Kremenek0964a062009-01-21 06:57:53 +00001193 if (T->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001194 return BindStruct(state, VR, InitVal);
Zhongxing Xud463d442008-11-02 12:13:30 +00001195
Zhongxing Xud91ee272009-06-23 09:02:15 +00001196 return Bind(state, ValMgr.makeLoc(VR), InitVal);
Zhongxing Xu17892752008-10-08 02:50:44 +00001197}
Zhongxing Xu53bcdd42008-10-21 05:29:26 +00001198
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001199// FIXME: this method should be merged into Bind().
Ted Kremenek67f28532009-06-17 22:02:04 +00001200const GRState *
1201RegionStoreManager::BindCompoundLiteral(const GRState *state,
1202 const CompoundLiteralExpr* CL,
1203 SVal V) {
1204
Zhongxing Xuf22679e2008-11-07 10:38:33 +00001205 CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL);
Ted Kremenek67f28532009-06-17 22:02:04 +00001206 return Bind(state, loc::MemRegionVal(R), V);
Zhongxing Xuf22679e2008-11-07 10:38:33 +00001207}
1208
Ted Kremenek67f28532009-06-17 22:02:04 +00001209const GRState *RegionStoreManager::BindArray(const GRState *state,
Ted Kremenek46537392009-07-16 01:33:37 +00001210 const TypedRegion* R,
Ted Kremenek67f28532009-06-17 22:02:04 +00001211 SVal Init) {
1212
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001213 QualType T = R->getValueType(getContext());
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001214 ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001215 QualType ElementTy = CAT->getElementType();
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001216
Ted Kremenek46537392009-07-16 01:33:37 +00001217 uint64_t size = CAT->getSize().getZExtValue();
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001218
1219 // Check if the init expr is a StringLiteral.
1220 if (isa<loc::MemRegionVal>(Init)) {
1221 const MemRegion* InitR = cast<loc::MemRegionVal>(Init).getRegion();
1222 const StringLiteral* S = cast<StringRegion>(InitR)->getStringLiteral();
1223 const char* str = S->getStrData();
1224 unsigned len = S->getByteLength();
1225 unsigned j = 0;
1226
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001227 // Copy bytes from the string literal into the target array. Trailing bytes
1228 // in the array that are not covered by the string literal are initialized
1229 // to zero.
Ted Kremenek46537392009-07-16 01:33:37 +00001230 for (uint64_t i = 0; i < size; ++i, ++j) {
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001231 if (j >= len)
1232 break;
1233
Ted Kremenek46537392009-07-16 01:33:37 +00001234 SVal Idx = ValMgr.makeArrayIndex(i);
1235 ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx, R,
1236 getContext());
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001237
Zhongxing Xud91ee272009-06-23 09:02:15 +00001238 SVal V = ValMgr.makeIntVal(str[j], sizeof(char)*8, true);
Ted Kremenek67f28532009-06-17 22:02:04 +00001239 state = Bind(state, loc::MemRegionVal(ER), V);
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001240 }
1241
Ted Kremenek67f28532009-06-17 22:02:04 +00001242 return state;
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001243 }
1244
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001245 nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001246 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
Ted Kremenek46537392009-07-16 01:33:37 +00001247 uint64_t i = 0;
1248
1249 for (; i < size; ++i, ++VI) {
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001250 // The init list might be shorter than the array length.
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001251 if (VI == VE)
1252 break;
1253
Ted Kremenek46537392009-07-16 01:33:37 +00001254 SVal Idx = ValMgr.makeArrayIndex(i);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001255 ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx, R, getContext());
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001256
1257 if (CAT->getElementType()->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001258 state = BindStruct(state, ER, *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001259 else
Zhongxing Xud91ee272009-06-23 09:02:15 +00001260 state = Bind(state, ValMgr.makeLoc(ER), *VI);
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001261 }
1262
Zhongxing Xue3a765f2009-06-24 00:56:31 +00001263 // If the init list is shorter than the array length, set the array default
1264 // value.
Ted Kremenek46537392009-07-16 01:33:37 +00001265 if (i < size) {
Zhongxing Xue3a765f2009-06-24 00:56:31 +00001266 if (ElementTy->isIntegerType()) {
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001267 SVal V = ValMgr.makeZeroVal(ElementTy);
Zhongxing Xue3a765f2009-06-24 00:56:31 +00001268 state = setDefaultValue(state, R, V);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001269 }
1270 }
1271
Ted Kremenek67f28532009-06-17 22:02:04 +00001272 return state;
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001273}
1274
Ted Kremenek67f28532009-06-17 22:02:04 +00001275const GRState *
1276RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,
1277 SVal V) {
1278
1279 if (!Features.supportsFields())
1280 return state;
1281
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001282 QualType T = R->getValueType(getContext());
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001283 assert(T->isStructureType());
1284
Ted Kremenek35366a62009-07-17 17:50:17 +00001285 const RecordType* RT = T->getAsRecordType();
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001286 RecordDecl* RD = RT->getDecl();
Zhongxing Xuc45a8252009-03-11 09:07:35 +00001287
1288 if (!RD->isDefinition())
Ted Kremenek67f28532009-06-17 22:02:04 +00001289 return state;
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001290
Ted Kremenek67f28532009-06-17 22:02:04 +00001291 // We may get non-CompoundVal accidentally due to imprecise cast logic.
1292 // Ignore them and kill the field values.
1293 if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
1294 return KillStruct(state, R);
Zhongxing Xu3f6978a2009-06-11 09:11:27 +00001295
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001296 nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001297 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001298
1299 RecordDecl::field_iterator FI, FE;
1300
Argyrios Kyrtzidis17945a02009-06-30 02:36:12 +00001301 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) {
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001302
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001303 if (VI == VE)
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001304 break;
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001305
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001306 QualType FTy = (*FI)->getType();
1307 FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
1308
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001309 if (Loc::IsLocType(FTy) || FTy->isIntegerType())
Zhongxing Xud91ee272009-06-23 09:02:15 +00001310 state = Bind(state, ValMgr.makeLoc(FR), *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001311 else if (FTy->isArrayType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001312 state = BindArray(state, FR, *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001313 else if (FTy->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001314 state = BindStruct(state, FR, *VI);
Zhongxing Xua82512a2008-10-24 08:42:28 +00001315 }
1316
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001317 // There may be fewer values in the initialize list than the fields of struct.
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001318 if (FI != FE)
1319 state = setDefaultValue(state, R, ValMgr.makeIntVal(0, false));
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001320
Ted Kremenek67f28532009-06-17 22:02:04 +00001321 return state;
Zhongxing Xuc3a05992008-11-19 11:06:24 +00001322}
1323
Ted Kremenek67f28532009-06-17 22:02:04 +00001324const GRState *RegionStoreManager::KillStruct(const GRState *state,
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001325 const TypedRegion* R){
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001326
Zhongxing Xue4df9c42009-06-25 05:52:16 +00001327 // Set the default value of the struct region to "unknown".
1328 state = state->set<RegionDefaultValue>(R, UnknownVal());
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001329
1330 // Remove all bindings for the subregions of the struct.
Zhongxing Xue4df9c42009-06-25 05:52:16 +00001331 Store store = state->getStore();
1332 RegionBindingsTy B = GetRegionBindings(store);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001333 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
Ted Kremenek67f28532009-06-17 22:02:04 +00001334 const MemRegion* R = I.getKey();
1335 if (const SubRegion* subRegion = dyn_cast<SubRegion>(R))
1336 if (subRegion->isSubRegionOf(R))
Zhongxing Xud91ee272009-06-23 09:02:15 +00001337 store = Remove(store, ValMgr.makeLoc(subRegion));
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001338 }
1339
Ted Kremenek67f28532009-06-17 22:02:04 +00001340 return state->makeWithStore(store);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001341}
1342
Ted Kremenek9af46f52009-06-16 22:36:44 +00001343//===----------------------------------------------------------------------===//
1344// Region views.
1345//===----------------------------------------------------------------------===//
1346
Ted Kremenek67f28532009-06-17 22:02:04 +00001347const GRState *RegionStoreManager::AddRegionView(const GRState *state,
1348 const MemRegion* View,
1349 const MemRegion* Base) {
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001350
1351 // First, retrieve the region view of the base region.
Ted Kremenek67f28532009-06-17 22:02:04 +00001352 const RegionViews* d = state->get<RegionViewMap>(Base);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001353 RegionViews L = d ? *d : RVFactory.GetEmptySet();
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001354
1355 // Now add View to the region view.
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001356 L = RVFactory.Add(L, View);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001357
1358 // Create a new state with the new region view.
Ted Kremenek67f28532009-06-17 22:02:04 +00001359 return state->set<RegionViewMap>(Base, L);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001360}
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001361
Ted Kremenek67f28532009-06-17 22:02:04 +00001362const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
1363 const MemRegion* View,
1364 const MemRegion* Base) {
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001365 // Retrieve the region view of the base region.
Ted Kremenek67f28532009-06-17 22:02:04 +00001366 const RegionViews* d = state->get<RegionViewMap>(Base);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001367
1368 // If the base region has no view, return.
1369 if (!d)
Ted Kremenek67f28532009-06-17 22:02:04 +00001370 return state;
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001371
1372 // Remove the view.
Ted Kremenek67f28532009-06-17 22:02:04 +00001373 return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View));
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001374}
Zhongxing Xu20794942009-05-06 08:33:50 +00001375
Zhongxing Xu88c675f2009-06-18 06:29:10 +00001376const GRState *RegionStoreManager::setCastType(const GRState *state,
1377 const MemRegion* R, QualType T) {
Zhongxing Xu82037252009-07-14 01:12:46 +00001378 // We do not record generic cast type, since we are using cast type to
1379 // invlidate regions, and generic type is meaningless for invalidating
1380 // regions.
1381 // If the region already has a cast type before, that type is preserved.
1382 // FIXME: is this the right thing to do?
1383 if (isGenericPtr(getContext(), T))
1384 return state;
Ted Kremenek67f28532009-06-17 22:02:04 +00001385 return state->set<RegionCasts>(R, T);
Zhongxing Xu20794942009-05-06 08:33:50 +00001386}
Zhongxing Xu264e9372009-05-12 10:10:00 +00001387
Ted Kremenek67f28532009-06-17 22:02:04 +00001388const GRState *RegionStoreManager::setDefaultValue(const GRState *state,
1389 const MemRegion* R, SVal V) {
1390 return state->set<RegionDefaultValue>(R, V);
Zhongxing Xu264e9372009-05-12 10:10:00 +00001391}
Ted Kremenek9af46f52009-06-16 22:36:44 +00001392
1393//===----------------------------------------------------------------------===//
1394// State pruning.
1395//===----------------------------------------------------------------------===//
1396
1397static void UpdateLiveSymbols(SVal X, SymbolReaper& SymReaper) {
1398 if (loc::MemRegionVal *XR = dyn_cast<loc::MemRegionVal>(&X)) {
1399 const MemRegion *R = XR->getRegion();
1400
1401 while (R) {
1402 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1403 SymReaper.markLive(SR->getSymbol());
1404 return;
1405 }
1406
1407 if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
1408 R = SR->getSuperRegion();
1409 continue;
1410 }
1411
1412 break;
1413 }
1414
1415 return;
1416 }
1417
1418 for (SVal::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();SI!=SE;++SI)
1419 SymReaper.markLive(*SI);
1420}
1421
Ted Kremenek67f28532009-06-17 22:02:04 +00001422Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
Ted Kremenek9af46f52009-06-16 22:36:44 +00001423 SymbolReaper& SymReaper,
1424 llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
Ted Kremenek67f28532009-06-17 22:02:04 +00001425{
Ted Kremenek9af46f52009-06-16 22:36:44 +00001426 Store store = state->getStore();
1427 RegionBindingsTy B = GetRegionBindings(store);
1428
1429 // Lazily constructed backmap from MemRegions to SubRegions.
1430 typedef llvm::ImmutableSet<const MemRegion*> SubRegionsTy;
1431 typedef llvm::ImmutableMap<const MemRegion*, SubRegionsTy> SubRegionsMapTy;
1432
1433 // FIXME: As a future optimization we can modifiy BumpPtrAllocator to have
1434 // the ability to reuse memory. This way we can keep TmpAlloc around as
1435 // an instance variable of RegionStoreManager (avoiding repeated malloc
1436 // overhead).
1437 llvm::BumpPtrAllocator TmpAlloc;
1438
1439 // Factory objects.
1440 SubRegionsMapTy::Factory SubRegMapF(TmpAlloc);
1441 SubRegionsTy::Factory SubRegF(TmpAlloc);
1442
1443 // The backmap from regions to subregions.
1444 SubRegionsMapTy SubRegMap = SubRegMapF.GetEmptyMap();
1445
1446 // Do a pass over the regions in the store. For VarRegions we check if
1447 // the variable is still live and if so add it to the list of live roots.
Ted Kremenek67f28532009-06-17 22:02:04 +00001448 // For other regions we populate our region backmap.
Ted Kremenek9af46f52009-06-16 22:36:44 +00001449 llvm::SmallVector<const MemRegion*, 10> IntermediateRoots;
1450
1451 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1452 IntermediateRoots.push_back(I.getKey());
1453 }
1454
1455 while (!IntermediateRoots.empty()) {
1456 const MemRegion* R = IntermediateRoots.back();
1457 IntermediateRoots.pop_back();
1458
1459 if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
Zhongxing Xu7abe0192009-06-30 12:32:59 +00001460 if (SymReaper.isLive(Loc, VR->getDecl())) {
Ted Kremenek9af46f52009-06-16 22:36:44 +00001461 RegionRoots.push_back(VR); // This is a live "root".
Zhongxing Xu7abe0192009-06-30 12:32:59 +00001462 }
Ted Kremenek9af46f52009-06-16 22:36:44 +00001463 }
1464 else if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
1465 if (SymReaper.isLive(SR->getSymbol()))
1466 RegionRoots.push_back(SR);
1467 }
1468 else {
1469 // Get the super region for R.
Ted Kremenek8b2ba312009-07-01 23:30:34 +00001470 const MemRegion* superR = cast<SubRegion>(R)->getSuperRegion();
Ted Kremenek9af46f52009-06-16 22:36:44 +00001471
1472 // Get the current set of subregions for SuperR.
Ted Kremenek8b2ba312009-07-01 23:30:34 +00001473 const SubRegionsTy* SRptr = SubRegMap.lookup(superR);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001474 SubRegionsTy SRs = SRptr ? *SRptr : SubRegF.GetEmptySet();
1475
1476 // Add R to the subregions of SuperR.
Ted Kremenek8b2ba312009-07-01 23:30:34 +00001477 SubRegMap = SubRegMapF.Add(SubRegMap, superR, SubRegF.Add(SRs, R));
Ted Kremenek9af46f52009-06-16 22:36:44 +00001478
1479 // Super region may be VarRegion or subregion of another VarRegion. Add it
1480 // to the work list.
Ted Kremenek8b2ba312009-07-01 23:30:34 +00001481 if (isa<SubRegion>(superR))
1482 IntermediateRoots.push_back(superR);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001483 }
1484 }
1485
1486 // Process the worklist of RegionRoots. This performs a "mark-and-sweep"
1487 // of the store. We want to find all live symbols and dead regions.
1488 llvm::SmallPtrSet<const MemRegion*, 10> Marked;
1489
1490 while (!RegionRoots.empty()) {
1491 // Dequeue the next region on the worklist.
1492 const MemRegion* R = RegionRoots.back();
1493 RegionRoots.pop_back();
1494
1495 // Check if we have already processed this region.
1496 if (Marked.count(R)) continue;
1497
1498 // Mark this region as processed. This is needed for termination in case
1499 // a region is referenced more than once.
1500 Marked.insert(R);
1501
1502 // Mark the symbol for any live SymbolicRegion as "live". This means we
1503 // should continue to track that symbol.
1504 if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
1505 SymReaper.markLive(SymR->getSymbol());
1506
1507 // Get the data binding for R (if any).
1508 RegionBindingsTy::data_type* Xptr = B.lookup(R);
1509 if (Xptr) {
1510 SVal X = *Xptr;
1511 UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
1512
Zhongxing Xu7abe0192009-06-30 12:32:59 +00001513 // If X is a region, then add it to the RegionRoots.
1514 if (const MemRegion *RX = X.getAsRegion()) {
1515 RegionRoots.push_back(RX);
1516
1517 // Mark the super region of the RX as live.
1518 // e.g.: int x; char *y = (char*) &x; if (*y) ...
1519 // 'y' => element region. 'x' is its super region.
1520 // We only add one level super region for now.
Zhongxing Xu5ff8e8c2009-07-01 02:12:57 +00001521 // FIXME: maybe multiple level of super regions should be added.
Zhongxing Xu7abe0192009-06-30 12:32:59 +00001522 if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) {
1523 RegionRoots.push_back(SR->getSuperRegion());
1524 }
1525 }
Ted Kremenek9af46f52009-06-16 22:36:44 +00001526 }
1527
1528 // Get the subregions of R. These are RegionRoots as well since they
1529 // represent values that are also bound to R.
1530 const SubRegionsTy* SRptr = SubRegMap.lookup(R);
1531 if (!SRptr) continue;
1532 SubRegionsTy SR = *SRptr;
1533
1534 for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)
1535 RegionRoots.push_back(*I);
Zhongxing Xu7abe0192009-06-30 12:32:59 +00001536
Ted Kremenek9af46f52009-06-16 22:36:44 +00001537 }
1538
1539 // We have now scanned the store, marking reachable regions and symbols
1540 // as live. We now remove all the regions that are dead from the store
1541 // as well as update DSymbols with the set symbols that are now dead.
1542 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1543 const MemRegion* R = I.getKey();
Ted Kremenek9af46f52009-06-16 22:36:44 +00001544 // If this region live? Is so, none of its symbols are dead.
1545 if (Marked.count(R))
1546 continue;
1547
1548 // Remove this dead region from the store.
Zhongxing Xud91ee272009-06-23 09:02:15 +00001549 store = Remove(store, ValMgr.makeLoc(R));
Ted Kremenek9af46f52009-06-16 22:36:44 +00001550
1551 // Mark all non-live symbols that this region references as dead.
1552 if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
1553 SymReaper.maybeDead(SymR->getSymbol());
1554
1555 SVal X = I.getData();
1556 SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
1557 for (; SI != SE; ++SI) SymReaper.maybeDead(*SI);
1558 }
1559
1560 return store;
1561}
1562
1563//===----------------------------------------------------------------------===//
1564// Utility methods.
1565//===----------------------------------------------------------------------===//
1566
Ted Kremenek53ba0b62009-06-24 23:06:47 +00001567void RegionStoreManager::print(Store store, llvm::raw_ostream& OS,
Ted Kremenek9af46f52009-06-16 22:36:44 +00001568 const char* nl, const char *sep) {
Ted Kremenek9af46f52009-06-16 22:36:44 +00001569 RegionBindingsTy B = GetRegionBindings(store);
1570 OS << "Store:" << nl;
1571
Ted Kremenek6f9b3a42009-07-13 23:53:06 +00001572 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
1573 OS << ' ' << I.getKey() << " : " << I.getData() << nl;
Ted Kremenek9af46f52009-06-16 22:36:44 +00001574}