blob: 2bb97e9f82ba5951e63c8f8293d0c2183a1a948d [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
Zhongxing Xubaf03a72008-11-24 09:44:56 +000030// Actual Store type.
Zhongxing Xu1c96b242008-10-17 05:57:07 +000031typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
Zhongxing Xubaf03a72008-11-24 09:44:56 +000032
Ted Kremenek50dc1b32008-12-24 01:05:03 +000033//===----------------------------------------------------------------------===//
Ted Kremenek9af46f52009-06-16 22:36:44 +000034// Fine-grained control of RegionStoreManager.
35//===----------------------------------------------------------------------===//
36
37namespace {
38struct VISIBILITY_HIDDEN minimal_features_tag {};
39struct VISIBILITY_HIDDEN maximal_features_tag {};
40
41class VISIBILITY_HIDDEN RegionStoreFeatures {
42 bool SupportsFields;
43 bool SupportsRemaining;
44
45public:
46 RegionStoreFeatures(minimal_features_tag) :
47 SupportsFields(false), SupportsRemaining(false) {}
48
49 RegionStoreFeatures(maximal_features_tag) :
50 SupportsFields(true), SupportsRemaining(false) {}
51
52 void enableFields(bool t) { SupportsFields = t; }
53
54 bool supportsFields() const { return SupportsFields; }
55 bool supportsRemaining() const { return SupportsRemaining; }
56};
57}
58
59//===----------------------------------------------------------------------===//
Ted Kremenek50dc1b32008-12-24 01:05:03 +000060// Region "Views"
61//===----------------------------------------------------------------------===//
62//
63// MemRegions can be layered on top of each other. This GDM entry tracks
64// what are the MemRegions that layer a given MemRegion.
65//
Zhongxing Xu5834ed62009-01-13 01:49:57 +000066typedef llvm::ImmutableSet<const MemRegion*> RegionViews;
Ted Kremenek50dc1b32008-12-24 01:05:03 +000067namespace { class VISIBILITY_HIDDEN RegionViewMap {}; }
68static int RegionViewMapIndex = 0;
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000069namespace clang {
Ted Kremenek50dc1b32008-12-24 01:05:03 +000070 template<> struct GRStateTrait<RegionViewMap>
71 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*,
72 RegionViews> > {
73
74 static void* GDMIndex() { return &RegionViewMapIndex; }
75 };
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000076}
Zhongxing Xu17892752008-10-08 02:50:44 +000077
Zhongxing Xu20794942009-05-06 08:33:50 +000078// RegionCasts records the current cast type of a region.
79namespace { class VISIBILITY_HIDDEN RegionCasts {}; }
80static int RegionCastsIndex = 0;
81namespace clang {
82 template<> struct GRStateTrait<RegionCasts>
83 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*,
84 QualType> > {
85 static void* GDMIndex() { return &RegionCastsIndex; }
86 };
87}
88
Ted Kremenek50dc1b32008-12-24 01:05:03 +000089//===----------------------------------------------------------------------===//
90// Region "Extents"
91//===----------------------------------------------------------------------===//
92//
93// MemRegions represent chunks of memory with a size (their "extent"). This
94// GDM entry tracks the extents for regions. Extents are in bytes.
Ted Kremenekd6cfbe42009-01-07 22:18:50 +000095//
Ted Kremenek50dc1b32008-12-24 01:05:03 +000096namespace { class VISIBILITY_HIDDEN RegionExtents {}; }
97static int RegionExtentsIndex = 0;
Zhongxing Xubaf03a72008-11-24 09:44:56 +000098namespace clang {
Ted Kremenek50dc1b32008-12-24 01:05:03 +000099 template<> struct GRStateTrait<RegionExtents>
100 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, SVal> > {
101 static void* GDMIndex() { return &RegionExtentsIndex; }
102 };
Zhongxing Xubaf03a72008-11-24 09:44:56 +0000103}
104
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000105//===----------------------------------------------------------------------===//
106// Region "killsets".
107//===----------------------------------------------------------------------===//
108//
Zhongxing Xu5834ed62009-01-13 01:49:57 +0000109// RegionStore lazily adds value bindings to regions when the analyzer handles
110// assignment statements. Killsets track which default values have been
111// killed, thus distinguishing between "unknown" values and default
112// values. Regions are added to killset only when they are assigned "unknown"
113// directly, otherwise we should have their value in the region bindings.
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000114//
115namespace { class VISIBILITY_HIDDEN RegionKills {}; }
Ted Kremenek2ed14be2008-12-05 00:47:52 +0000116static int RegionKillsIndex = 0;
Ted Kremenekc48ea6e2008-12-04 02:08:27 +0000117namespace clang {
Ted Kremenek2ed14be2008-12-05 00:47:52 +0000118 template<> struct GRStateTrait<RegionKills>
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000119 : public GRStatePartialTrait< llvm::ImmutableSet<const MemRegion*> > {
Ted Kremenek2ed14be2008-12-05 00:47:52 +0000120 static void* GDMIndex() { return &RegionKillsIndex; }
Ted Kremenekc48ea6e2008-12-04 02:08:27 +0000121 };
122}
123
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000124//===----------------------------------------------------------------------===//
Zhongxing Xu5834ed62009-01-13 01:49:57 +0000125// Regions with default values.
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000126//===----------------------------------------------------------------------===//
127//
Zhongxing Xu5834ed62009-01-13 01:49:57 +0000128// This GDM entry tracks what regions have a default value if they have no bound
129// value and have not been killed.
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000130//
131namespace { class VISIBILITY_HIDDEN RegionDefaultValue {}; }
132static int RegionDefaultValueIndex = 0;
133namespace clang {
134 template<> struct GRStateTrait<RegionDefaultValue>
135 : public GRStatePartialTrait<llvm::ImmutableMap<const MemRegion*, SVal> > {
136 static void* GDMIndex() { return &RegionDefaultValueIndex; }
137 };
138}
139
140//===----------------------------------------------------------------------===//
141// Main RegionStore logic.
142//===----------------------------------------------------------------------===//
Ted Kremenekc48ea6e2008-12-04 02:08:27 +0000143
Zhongxing Xu17892752008-10-08 02:50:44 +0000144namespace {
145
Ted Kremenek59e8f112009-03-03 01:35:36 +0000146class VISIBILITY_HIDDEN RegionStoreSubRegionMap : public SubRegionMap {
147 typedef llvm::DenseMap<const MemRegion*,
148 llvm::ImmutableSet<const MemRegion*> > Map;
149
150 llvm::ImmutableSet<const MemRegion*>::Factory F;
151 Map M;
152
153public:
154 void add(const MemRegion* Parent, const MemRegion* SubRegion) {
155 Map::iterator I = M.find(Parent);
156 M.insert(std::make_pair(Parent,
157 F.Add(I == M.end() ? F.GetEmptySet() : I->second, SubRegion)));
158 }
159
160 ~RegionStoreSubRegionMap() {}
161
Ted Kremenek5dc27462009-03-03 02:51:43 +0000162 bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
Ted Kremenek59e8f112009-03-03 01:35:36 +0000163 Map::iterator I = M.find(Parent);
164
165 if (I == M.end())
Ted Kremenek5dc27462009-03-03 02:51:43 +0000166 return true;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000167
168 llvm::ImmutableSet<const MemRegion*> S = I->second;
169 for (llvm::ImmutableSet<const MemRegion*>::iterator SI=S.begin(),SE=S.end();
170 SI != SE; ++SI) {
171 if (!V.Visit(Parent, *SI))
Ted Kremenek5dc27462009-03-03 02:51:43 +0000172 return false;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000173 }
Ted Kremenek5dc27462009-03-03 02:51:43 +0000174
175 return true;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000176 }
177};
178
Zhongxing Xu17892752008-10-08 02:50:44 +0000179class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
Ted Kremenek9af46f52009-06-16 22:36:44 +0000180 const RegionStoreFeatures Features;
Zhongxing Xu17892752008-10-08 02:50:44 +0000181 RegionBindingsTy::Factory RBFactory;
Ted Kremenek50dc1b32008-12-24 01:05:03 +0000182 RegionViews::Factory RVFactory;
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000183
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000184 const MemRegion* SelfRegion;
185 const ImplicitParamDecl *SelfDecl;
Zhongxing Xu17892752008-10-08 02:50:44 +0000186
187public:
Ted Kremenek9af46f52009-06-16 22:36:44 +0000188 RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
Ted Kremenekc62abc12009-04-21 21:51:34 +0000189 : StoreManager(mgr),
Ted Kremenek9af46f52009-06-16 22:36:44 +0000190 Features(f),
Ted Kremenekd6cfbe42009-01-07 22:18:50 +0000191 RBFactory(mgr.getAllocator()),
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000192 RVFactory(mgr.getAllocator()),
Ted Kremenekc62abc12009-04-21 21:51:34 +0000193 SelfRegion(0), SelfDecl(0) {
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000194 if (const ObjCMethodDecl* MD =
195 dyn_cast<ObjCMethodDecl>(&StateMgr.getCodeDecl()))
196 SelfDecl = MD->getSelfDecl();
197 }
Zhongxing Xu17892752008-10-08 02:50:44 +0000198
199 virtual ~RegionStoreManager() {}
200
Ted Kremenek14453bf2009-03-03 19:02:42 +0000201 SubRegionMap* getSubRegionMap(const GRState *state);
Ted Kremenek59e8f112009-03-03 01:35:36 +0000202
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000203 /// getLValueString - Returns an SVal representing the lvalue of a
204 /// StringLiteral. Within RegionStore a StringLiteral has an
205 /// associated StringRegion, and the lvalue of a StringLiteral is
206 /// the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000207 SVal getLValueString(const GRState *state, const StringLiteral* S);
Zhongxing Xu143bf822008-10-25 14:18:57 +0000208
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000209 /// getLValueCompoundLiteral - Returns an SVal representing the
210 /// lvalue of a compound literal. Within RegionStore a compound
211 /// literal has an associated region, and the lvalue of the
212 /// compound literal is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000213 SVal getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr*);
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000214
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000215 /// getLValueVar - Returns an SVal that represents the lvalue of a
216 /// variable. Within RegionStore a variable has an associated
217 /// VarRegion, and the lvalue of the variable is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000218 SVal getLValueVar(const GRState *state, const VarDecl* VD);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000219
Ted Kremenek67f28532009-06-17 22:02:04 +0000220 SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000221
Ted Kremenek67f28532009-06-17 22:02:04 +0000222 SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D);
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000223
Ted Kremenek67f28532009-06-17 22:02:04 +0000224 SVal getLValueFieldOrIvar(const GRState *state, SVal Base, const Decl* D);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000225
Ted Kremenek67f28532009-06-17 22:02:04 +0000226 SVal getLValueElement(const GRState *state, QualType elementType,
Ted Kremenekf936f452009-05-04 06:18:28 +0000227 SVal Base, SVal Offset);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000228
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000229
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000230 /// ArrayToPointer - Emulates the "decay" of an array to a pointer
231 /// type. 'Array' represents the lvalue of the array being decayed
232 /// to a pointer, and the returned SVal represents the decayed
233 /// version of that lvalue (i.e., a pointer to the first element of
234 /// the array). This is called by GRExprEngine when evaluating
235 /// casts from arrays to pointers.
Zhongxing Xuf1d537f2009-03-30 05:55:46 +0000236 SVal ArrayToPointer(Loc Array);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000237
Ted Kremenek67f28532009-06-17 22:02:04 +0000238 CastResult CastRegion(const GRState *state, const MemRegion* R,
Zhongxing Xu88980592009-05-06 02:42:32 +0000239 QualType CastToTy);
240
Ted Kremenek53ba0b62009-06-24 23:06:47 +0000241 SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,Loc L,
242 NonLoc R);
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000243
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000244 Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); }
Ted Kremenek9deb0e32008-10-24 20:32:16 +0000245
246 /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
247 /// 'this' object (C++). When used when analyzing a normal function this
248 /// method returns NULL.
249 const MemRegion* getSelfRegion(Store) {
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000250 if (!SelfDecl)
251 return 0;
252
253 if (!SelfRegion) {
254 const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(&StateMgr.getCodeDecl());
255 SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
256 MRMgr.getHeapRegion());
257 }
258
259 return SelfRegion;
Ted Kremenek9deb0e32008-10-24 20:32:16 +0000260 }
Ted Kremenek67f28532009-06-17 22:02:04 +0000261
262 //===-------------------------------------------------------------------===//
263 // Binding values to regions.
264 //===-------------------------------------------------------------------===//
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000265
Ted Kremenek67f28532009-06-17 22:02:04 +0000266 const GRState *Bind(const GRState *state, Loc LV, SVal V);
267
268 const GRState *BindCompoundLiteral(const GRState *state,
269 const CompoundLiteralExpr* CL, SVal V);
270
271 const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal);
272
273 const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
274 return state;
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000275 }
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000276
Ted Kremenek67f28532009-06-17 22:02:04 +0000277 /// BindStruct - Bind a compound value to a structure.
278 const GRState *BindStruct(const GRState *, const TypedRegion* R, SVal V);
279
280 const GRState *BindArray(const GRState *state, const TypedRegion* R, SVal V);
281
282 /// KillStruct - Set the entire struct to unknown.
283 const GRState *KillStruct(const GRState *state, const TypedRegion* R);
284
285 const GRState *setDefaultValue(const GRState *state, const MemRegion* R, SVal V);
286
287 Store Remove(Store store, Loc LV);
288
289 //===------------------------------------------------------------------===//
290 // Loading values from regions.
291 //===------------------------------------------------------------------===//
292
293 /// The high level logic for this method is this:
294 /// Retrieve (L)
295 /// if L has binding
296 /// return L's binding
297 /// else if L is in killset
298 /// return unknown
299 /// else
300 /// if L is on stack or heap
301 /// return undefined
302 /// else
303 /// return symbolic
304 SVal Retrieve(const GRState *state, Loc L, QualType T = QualType());
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000305
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000306 SVal RetrieveElement(const GRState* state, const ElementRegion* R);
307
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000308 SVal RetrieveField(const GRState* state, const FieldRegion* R);
309
Ted Kremenek67f28532009-06-17 22:02:04 +0000310 /// Retrieve the values in a struct and return a CompoundVal, used when doing
311 /// struct copy:
312 /// struct s x, y;
313 /// x = y;
314 /// y's value is retrieved by this method.
315 SVal RetrieveStruct(const GRState *St, const TypedRegion* R);
316
317 SVal RetrieveArray(const GRState *St, const TypedRegion* R);
318
319 //===------------------------------------------------------------------===//
320 // State pruning.
321 //===------------------------------------------------------------------===//
322
323 /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values.
324 /// It returns a new Store with these values removed.
325 Store RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper,
326 llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
327
328 //===------------------------------------------------------------------===//
329 // Region "extents".
330 //===------------------------------------------------------------------===//
331
332 const GRState *setExtent(const GRState *state, const MemRegion* R, SVal Extent);
333 SVal getSizeInElements(const GRState *state, const MemRegion* R);
334
335 //===------------------------------------------------------------------===//
336 // Region "views".
337 //===------------------------------------------------------------------===//
338
339 const GRState *AddRegionView(const GRState *state, const MemRegion* View,
340 const MemRegion* Base);
341
342 const GRState *RemoveRegionView(const GRState *state, const MemRegion* View,
343 const MemRegion* Base);
344
345 //===------------------------------------------------------------------===//
346 // Utility methods.
347 //===------------------------------------------------------------------===//
348
349 const GRState *setCastType(const GRState *state, const MemRegion* R, QualType T);
Zhongxing Xubaf03a72008-11-24 09:44:56 +0000350
Zhongxing Xu17892752008-10-08 02:50:44 +0000351 static inline RegionBindingsTy GetRegionBindings(Store store) {
Zhongxing Xu9c9ca082008-12-16 02:36:30 +0000352 return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
Zhongxing Xu17892752008-10-08 02:50:44 +0000353 }
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000354
Ted Kremenek53ba0b62009-06-24 23:06:47 +0000355 void print(Store store, llvm::raw_ostream& Out, const char* nl,
356 const char *sep);
Zhongxing Xu24194ef2008-10-24 01:38:55 +0000357
358 void iterBindings(Store store, BindingsHandler& f) {
359 // FIXME: Implement.
360 }
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +0000361
Ted Kremenek67f28532009-06-17 22:02:04 +0000362 // FIXME: Remove.
363 BasicValueFactory& getBasicVals() {
364 return StateMgr.getBasicVals();
365 }
366
367 // FIXME: Remove.
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +0000368 ASTContext& getContext() { return StateMgr.getContext(); }
Zhongxing Xua15f7ac2009-05-08 01:33:18 +0000369
Ted Kremenek67f28532009-06-17 22:02:04 +0000370 // FIXME: Use ValueManager?
371 SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
Zhongxing Xu17892752008-10-08 02:50:44 +0000372};
373
374} // end anonymous namespace
375
Ted Kremenek9af46f52009-06-16 22:36:44 +0000376//===----------------------------------------------------------------------===//
377// RegionStore creation.
378//===----------------------------------------------------------------------===//
379
380StoreManager *clang::CreateRegionStoreManager(GRStateManager& StMgr) {
381 RegionStoreFeatures F = maximal_features_tag();
382 return new RegionStoreManager(StMgr, F);
383}
384
385StoreManager *clang::CreateFieldsOnlyRegionStoreManager(GRStateManager &StMgr) {
386 RegionStoreFeatures F = minimal_features_tag();
387 F.enableFields(true);
388 return new RegionStoreManager(StMgr, F);
Ted Kremenek95c7b002008-10-24 01:04:59 +0000389}
390
Ted Kremenek14453bf2009-03-03 19:02:42 +0000391SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) {
Ted Kremenek59e8f112009-03-03 01:35:36 +0000392 RegionBindingsTy B = GetRegionBindings(state->getStore());
393 RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
394
395 for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
396 if (const SubRegion* R = dyn_cast<SubRegion>(I.getKey()))
397 M->add(R->getSuperRegion(), R);
398 }
399
Ted Kremenek14453bf2009-03-03 19:02:42 +0000400 return M;
Ted Kremenek59e8f112009-03-03 01:35:36 +0000401}
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000402
Ted Kremenek9af46f52009-06-16 22:36:44 +0000403//===----------------------------------------------------------------------===//
404// getLValueXXX methods.
405//===----------------------------------------------------------------------===//
406
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000407/// getLValueString - Returns an SVal representing the lvalue of a
408/// StringLiteral. Within RegionStore a StringLiteral has an
409/// associated StringRegion, and the lvalue of a StringLiteral is the
410/// lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000411SVal RegionStoreManager::getLValueString(const GRState *St,
Zhongxing Xu143bf822008-10-25 14:18:57 +0000412 const StringLiteral* S) {
413 return loc::MemRegionVal(MRMgr.getStringRegion(S));
414}
415
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000416/// getLValueVar - Returns an SVal that represents the lvalue of a
417/// variable. Within RegionStore a variable has an associated
418/// VarRegion, and the lvalue of the variable is the lvalue of that region.
Ted Kremenek67f28532009-06-17 22:02:04 +0000419SVal RegionStoreManager::getLValueVar(const GRState *St, const VarDecl* VD) {
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000420 return loc::MemRegionVal(MRMgr.getVarRegion(VD));
421}
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000422
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000423/// getLValueCompoundLiteral - Returns an SVal representing the lvalue
424/// of a compound literal. Within RegionStore a compound literal
425/// has an associated region, and the lvalue of the compound literal
426/// is the lvalue of that region.
427SVal
Ted Kremenek67f28532009-06-17 22:02:04 +0000428RegionStoreManager::getLValueCompoundLiteral(const GRState *St,
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000429 const CompoundLiteralExpr* CL) {
Zhongxing Xuf22679e2008-11-07 10:38:33 +0000430 return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL));
431}
432
Ted Kremenek67f28532009-06-17 22:02:04 +0000433SVal RegionStoreManager::getLValueIvar(const GRState *St, const ObjCIvarDecl* D,
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000434 SVal Base) {
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000435 return getLValueFieldOrIvar(St, Base, D);
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000436}
437
Ted Kremenek67f28532009-06-17 22:02:04 +0000438SVal RegionStoreManager::getLValueField(const GRState *St, SVal Base,
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000439 const FieldDecl* D) {
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000440 return getLValueFieldOrIvar(St, Base, D);
441}
442
Ted Kremenek67f28532009-06-17 22:02:04 +0000443SVal RegionStoreManager::getLValueFieldOrIvar(const GRState *St, SVal Base,
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000444 const Decl* D) {
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000445 if (Base.isUnknownOrUndef())
446 return Base;
447
448 Loc BaseL = cast<Loc>(Base);
449 const MemRegion* BaseR = 0;
450
451 switch (BaseL.getSubKind()) {
452 case loc::MemRegionKind:
453 BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
454 break;
455
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000456 case loc::GotoLabelKind:
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000457 // These are anormal cases. Flag an undefined value.
458 return UndefinedVal();
459
460 case loc::ConcreteIntKind:
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000461 // While these seem funny, this can happen through casts.
462 // FIXME: What we should return is the field offset. For example,
463 // add the field offset to the integer value. That way funny things
464 // like this work properly: &(((struct foo *) 0xa)->f)
465 return Base;
466
467 default:
Zhongxing Xu13d1ee22008-11-07 08:57:30 +0000468 assert(0 && "Unhandled Base.");
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000469 return Base;
470 }
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000471
472 // NOTE: We must have this check first because ObjCIvarDecl is a subclass
473 // of FieldDecl.
474 if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D))
475 return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000476
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000477 return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
Zhongxing Xuc4bf72c2008-10-22 13:44:38 +0000478}
479
Ted Kremenek67f28532009-06-17 22:02:04 +0000480SVal RegionStoreManager::getLValueElement(const GRState *St,
Ted Kremenekf936f452009-05-04 06:18:28 +0000481 QualType elementType,
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000482 SVal Base, SVal Offset) {
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000483
Ted Kremenekde7ec632009-03-09 22:44:49 +0000484 // If the base is an unknown or undefined value, just return it back.
485 // FIXME: For absolute pointer addresses, we just return that value back as
486 // well, although in reality we should return the offset added to that
487 // value.
488 if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
Zhongxing Xu4a1513e2008-10-27 12:23:17 +0000489 return Base;
490
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000491 // Only handle integer offsets... for now.
492 if (!isa<nonloc::ConcreteInt>(Offset))
Zhongxing Xue4d13932008-11-13 09:48:44 +0000493 return UnknownVal();
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000494
Zhongxing Xuce760782009-05-09 13:20:07 +0000495 const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000496
497 // Pointer of any type can be cast and used as array base.
498 const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
499
500 if (!ElemR) {
501 //
502 // If the base region is not an ElementRegion, create one.
503 // This can happen in the following example:
504 //
505 // char *p = __builtin_alloc(10);
506 // p[1] = 8;
507 //
Zhongxing Xuce760782009-05-09 13:20:07 +0000508 // Observe that 'p' binds to an AllocaRegion.
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000509 //
Zhongxing Xu5ea2ffc2009-02-19 08:37:16 +0000510
511 // Offset might be unsigned. We have to convert it to signed ConcreteInt.
512 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&Offset)) {
513 const llvm::APSInt& OffI = CI->getValue();
514 if (OffI.isUnsigned()) {
515 llvm::APSInt Tmp = OffI;
516 Tmp.setIsSigned(true);
Zhongxing Xud91ee272009-06-23 09:02:15 +0000517 Offset = ValMgr.makeIntVal(Tmp);
Zhongxing Xu5ea2ffc2009-02-19 08:37:16 +0000518 }
519 }
Ted Kremenekf936f452009-05-04 06:18:28 +0000520 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000521 BaseRegion, getContext()));
Zhongxing Xue4d13932008-11-13 09:48:44 +0000522 }
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000523
524 SVal BaseIdx = ElemR->getIndex();
525
526 if (!isa<nonloc::ConcreteInt>(BaseIdx))
527 return UnknownVal();
528
529 const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
530 const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
531 assert(BaseIdxI.isSigned());
532
533 // FIXME: This appears to be the assumption of this code. We should review
534 // whether or not BaseIdxI.getBitWidth() < OffI.getBitWidth(). If it
535 // can't we need to put a comment here. If it can, we should handle it.
536 assert(BaseIdxI.getBitWidth() >= OffI.getBitWidth());
Zhongxing Xue4d13932008-11-13 09:48:44 +0000537
Zhongxing Xuce760782009-05-09 13:20:07 +0000538 const MemRegion *ArrayR = ElemR->getSuperRegion();
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000539 SVal NewIdx;
540
541 if (OffI.isUnsigned() || OffI.getBitWidth() < BaseIdxI.getBitWidth()) {
542 // 'Offset' might be unsigned. We have to convert it to signed and
543 // possibly extend it.
544 llvm::APSInt Tmp = OffI;
545
546 if (OffI.getBitWidth() < BaseIdxI.getBitWidth())
547 Tmp.extend(BaseIdxI.getBitWidth());
548
549 Tmp.setIsSigned(true);
550 Tmp += BaseIdxI; // Compute the new offset.
Zhongxing Xud91ee272009-06-23 09:02:15 +0000551 NewIdx = ValMgr.makeIntVal(Tmp);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000552 }
Ted Kremeneka7ac9442009-01-22 20:27:48 +0000553 else
554 NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI));
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000555
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000556 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
557 getContext()));
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000558}
559
Ted Kremenek9af46f52009-06-16 22:36:44 +0000560//===----------------------------------------------------------------------===//
561// Extents for regions.
562//===----------------------------------------------------------------------===//
563
Ted Kremenek67f28532009-06-17 22:02:04 +0000564SVal RegionStoreManager::getSizeInElements(const GRState *state,
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000565 const MemRegion* R) {
566 if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
567 // Get the type of the variable.
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000568 QualType T = VR->getDesugaredValueType(getContext());
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000569
Ted Kremenek14553ab2009-01-30 00:08:43 +0000570 // FIXME: Handle variable-length arrays.
571 if (isa<VariableArrayType>(T))
572 return UnknownVal();
573
574 if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
575 // return the size as signed integer.
Zhongxing Xud91ee272009-06-23 09:02:15 +0000576 return ValMgr.makeIntVal(CAT->getSize(), false);
Ted Kremenek14553ab2009-01-30 00:08:43 +0000577 }
Zhongxing Xu20794942009-05-06 08:33:50 +0000578
Ted Kremenek67f28532009-06-17 22:02:04 +0000579 const QualType* CastTy = state->get<RegionCasts>(VR);
Zhongxing Xu41fd0182009-05-06 11:51:48 +0000580
Zhongxing Xue6536af2009-05-08 02:00:55 +0000581 // If the VarRegion is cast to other type, compute the size with respect to
582 // that type.
Zhongxing Xu41fd0182009-05-06 11:51:48 +0000583 if (CastTy) {
584 QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000585 QualType VarTy = VR->getValueType(getContext());
Zhongxing Xue6536af2009-05-08 02:00:55 +0000586 uint64_t EleSize = getContext().getTypeSize(EleTy);
587 uint64_t VarSize = getContext().getTypeSize(VarTy);
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000588 assert(VarSize != 0);
Zhongxing Xud91ee272009-06-23 09:02:15 +0000589 return ValMgr.makeIntVal(VarSize/EleSize, false);
Zhongxing Xu41fd0182009-05-06 11:51:48 +0000590 }
591
Ted Kremenek14553ab2009-01-30 00:08:43 +0000592 // Clients can use ordinary variables as if they were arrays. These
593 // essentially are arrays of size 1.
Zhongxing Xud91ee272009-06-23 09:02:15 +0000594 return ValMgr.makeIntVal(1, false);
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000595 }
596
597 if (const StringRegion* SR = dyn_cast<StringRegion>(R)) {
Zhongxing Xu6613d082008-11-24 02:18:56 +0000598 const StringLiteral* Str = SR->getStringLiteral();
Zhongxing Xud0fd3b72008-11-24 02:30:48 +0000599 // We intentionally made the size value signed because it participates in
600 // operations with signed indices.
Zhongxing Xud91ee272009-06-23 09:02:15 +0000601 return ValMgr.makeIntVal(Str->getByteLength()+1, false);
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000602 }
603
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000604 if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) {
605 // FIXME: Unsupported yet.
606 FR = 0;
607 return UnknownVal();
608 }
Zhongxing Xu369f4292008-11-22 13:23:00 +0000609
Zhongxing Xu02ebefb2009-02-06 08:51:30 +0000610 if (isa<SymbolicRegion>(R)) {
Zhongxing Xua48f7372009-02-06 08:44:27 +0000611 return UnknownVal();
612 }
613
Zhongxing Xuce760782009-05-09 13:20:07 +0000614 if (isa<AllocaRegion>(R)) {
615 return UnknownVal();
616 }
617
Zhongxing Xuccb16162009-05-06 08:08:27 +0000618 if (isa<ElementRegion>(R)) {
619 return UnknownVal();
620 }
621
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000622 assert(0 && "Other regions are not supported yet.");
Ted Kremeneka21362d2009-01-06 19:12:06 +0000623 return UnknownVal();
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000624}
625
Ted Kremenek67f28532009-06-17 22:02:04 +0000626const GRState *RegionStoreManager::setExtent(const GRState *state,
627 const MemRegion *region,
628 SVal extent) {
629 return state->set<RegionExtents>(region, extent);
Ted Kremenek9af46f52009-06-16 22:36:44 +0000630}
631
632//===----------------------------------------------------------------------===//
633// Location and region casting.
634//===----------------------------------------------------------------------===//
635
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000636/// ArrayToPointer - Emulates the "decay" of an array to a pointer
637/// type. 'Array' represents the lvalue of the array being decayed
638/// to a pointer, and the returned SVal represents the decayed
639/// version of that lvalue (i.e., a pointer to the first element of
640/// the array). This is called by GRExprEngine when evaluating casts
641/// from arrays to pointers.
Zhongxing Xuf1d537f2009-03-30 05:55:46 +0000642SVal RegionStoreManager::ArrayToPointer(Loc Array) {
Ted Kremenekabb042f2008-12-13 19:24:37 +0000643 if (!isa<loc::MemRegionVal>(Array))
644 return UnknownVal();
645
646 const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
647 const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R);
648
Ted Kremenekbbee1a72009-01-13 01:03:27 +0000649 if (!ArrayR)
Ted Kremenekabb042f2008-12-13 19:24:37 +0000650 return UnknownVal();
651
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000652 // Strip off typedefs from the ArrayRegion's ValueType.
653 QualType T = ArrayR->getValueType(getContext())->getDesugaredType();
Ted Kremenekf936f452009-05-04 06:18:28 +0000654 ArrayType *AT = cast<ArrayType>(T);
655 T = AT->getElementType();
656
Zhongxing Xu63123d82008-11-23 04:30:35 +0000657 nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false));
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000658 ElementRegion* ER = MRMgr.getElementRegion(T, Idx, ArrayR, getContext());
Zhongxing Xu0b7e6422008-10-26 02:23:57 +0000659
660 return loc::MemRegionVal(ER);
Zhongxing Xub1d542a2008-10-24 01:09:32 +0000661}
662
Zhongxing Xu88980592009-05-06 02:42:32 +0000663RegionStoreManager::CastResult
Ted Kremenek67f28532009-06-17 22:02:04 +0000664RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
Zhongxing Xu41fd0182009-05-06 11:51:48 +0000665 QualType CastToTy) {
Zhongxing Xu88980592009-05-06 02:42:32 +0000666
667 ASTContext& Ctx = StateMgr.getContext();
668
669 // We need to know the real type of CastToTy.
670 QualType ToTy = Ctx.getCanonicalType(CastToTy);
671
672 // Check cast to ObjCQualifiedID type.
Steve Naroffd1b3c2d2009-06-17 22:40:22 +0000673 if (ToTy->isObjCQualifiedIdType()) {
Zhongxing Xu88980592009-05-06 02:42:32 +0000674 // FIXME: Record the type information aside.
675 return CastResult(state, R);
676 }
677
678 // CodeTextRegion should be cast to only function pointer type.
679 if (isa<CodeTextRegion>(R)) {
Zhongxing Xu99823a72009-06-22 08:36:10 +0000680 assert(CastToTy->isFunctionPointerType() || CastToTy->isBlockPointerType()
681 || (CastToTy->isPointerType()
682 && CastToTy->getAsPointerType()->getPointeeType()->isVoidType()));
Zhongxing Xu88980592009-05-06 02:42:32 +0000683 return CastResult(state, R);
684 }
685
Zhongxing Xudb3a0982009-05-09 10:03:08 +0000686 // Now assume we are casting from pointer to pointer. Other cases should
687 // already be handled.
Zhongxing Xu88980592009-05-06 02:42:32 +0000688 QualType PointeeTy = cast<PointerType>(ToTy.getTypePtr())->getPointeeType();
689
Zhongxing Xu88980592009-05-06 02:42:32 +0000690 // Process region cast according to the kind of the region being cast.
691
Zhongxing Xu88980592009-05-06 02:42:32 +0000692 // FIXME: Need to handle arbitrary downcasts.
Zhongxing Xu88980592009-05-06 02:42:32 +0000693 if (isa<SymbolicRegion>(R) || isa<AllocaRegion>(R)) {
Zhongxing Xuce760782009-05-09 13:20:07 +0000694 state = setCastType(state, R, ToTy);
695 return CastResult(state, R);
Zhongxing Xu88980592009-05-06 02:42:32 +0000696 }
697
698 // VarRegion, ElementRegion, and FieldRegion has an inherent type. Normally
699 // they should not be cast. We only layer an ElementRegion when the cast-to
700 // pointee type is of smaller size. In other cases, we return the original
701 // VarRegion.
702 if (isa<VarRegion>(R) || isa<ElementRegion>(R) || isa<FieldRegion>(R)
703 || isa<ObjCIvarRegion>(R) || isa<CompoundLiteralRegion>(R)) {
Zhongxing Xu2572eda2009-05-08 07:28:25 +0000704 // If the pointee type is incomplete, do not compute its size, and return
705 // the original region.
706 if (const RecordType *RT = dyn_cast<RecordType>(PointeeTy.getTypePtr())) {
707 const RecordDecl *D = RT->getDecl();
708 if (!D->getDefinition(getContext()))
709 return CastResult(state, R);
710 }
711
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000712 QualType ObjTy = cast<TypedRegion>(R)->getValueType(getContext());
Zhongxing Xufb1e3312009-05-08 02:12:59 +0000713 uint64_t PointeeTySize = getContext().getTypeSize(PointeeTy);
714 uint64_t ObjTySize = getContext().getTypeSize(ObjTy);
715
Zhongxing Xu5bf32872009-05-09 15:34:29 +0000716 if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000717 (ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
718 ObjTySize == 0 /* R has 'void*' type. */) {
Zhongxing Xu20794942009-05-06 08:33:50 +0000719 // Record the cast type of the region.
720 state = setCastType(state, R, ToTy);
721
Zhongxing Xuccb16162009-05-06 08:08:27 +0000722 SVal Idx = ValMgr.makeZeroArrayIndex();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000723 ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext());
Zhongxing Xuccb16162009-05-06 08:08:27 +0000724 return CastResult(state, ER);
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000725 } else {
726 state = setCastType(state, R, ToTy);
Zhongxing Xuccb16162009-05-06 08:08:27 +0000727 return CastResult(state, R);
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000728 }
Zhongxing Xu88980592009-05-06 02:42:32 +0000729 }
730
Zhongxing Xu88980592009-05-06 02:42:32 +0000731 if (isa<ObjCObjectRegion>(R)) {
732 return CastResult(state, R);
733 }
734
735 assert(0 && "Unprocessed region.");
Daniel Dunbar4e609002009-05-18 16:48:48 +0000736 return 0;
Zhongxing Xu88980592009-05-06 02:42:32 +0000737}
738
Ted Kremenek9af46f52009-06-16 22:36:44 +0000739//===----------------------------------------------------------------------===//
740// Pointer arithmetic.
741//===----------------------------------------------------------------------===//
742
Zhongxing Xu262fd032009-05-20 09:00:16 +0000743SVal RegionStoreManager::EvalBinOp(const GRState *state,
744 BinaryOperator::Opcode Op, Loc L, NonLoc R) {
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000745 // Assume the base location is MemRegionVal.
Ted Kremenek5dc27462009-03-03 02:51:43 +0000746 if (!isa<loc::MemRegionVal>(L))
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000747 return UnknownVal();
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000748
Zhongxing Xua1718c72009-04-03 07:33:13 +0000749 const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000750 const ElementRegion *ER = 0;
Zhongxing Xu262fd032009-05-20 09:00:16 +0000751
752 // If the operand is a symbolic or alloca region, create the first element
753 // region on it.
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000754 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) {
Zhongxing Xu005f07b2009-06-19 04:51:14 +0000755 QualType T;
756 // If the SymbolicRegion was cast to another type, use that type.
757 if (const QualType *t = state->get<RegionCasts>(SR)) {
758 T = *t;
759 } else {
760 // Otherwise use the symbol's type.
761 SymbolRef Sym = SR->getSymbol();
762 T = Sym->getType(getContext());
763 }
Zhongxing Xu53454dc2009-06-12 03:59:12 +0000764 QualType EleTy = T->getAsPointerType()->getPointeeType();
Zhongxing Xua1718c72009-04-03 07:33:13 +0000765
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000766 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000767 ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
Zhongxing Xu262fd032009-05-20 09:00:16 +0000768 }
769 else if (const AllocaRegion *AR = dyn_cast<AllocaRegion>(MR)) {
770 // Get the alloca region's current cast type.
Zhongxing Xu262fd032009-05-20 09:00:16 +0000771
Ted Kremenek67f28532009-06-17 22:02:04 +0000772
773 GRStateTrait<RegionCasts>::lookup_type T = state->get<RegionCasts>(AR);
Zhongxing Xu262fd032009-05-20 09:00:16 +0000774 assert(T && "alloca region has no type.");
775 QualType EleTy = cast<PointerType>(T->getTypePtr())->getPointeeType();
776 SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000777 ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
Zhongxing Xu262fd032009-05-20 09:00:16 +0000778 }
Zhongxing Xu5414a5c2009-06-21 13:24:24 +0000779 else if (isa<FieldRegion>(MR)) {
780 // Not track pointer arithmetic on struct fields.
781 return UnknownVal();
782 }
783 else {
Zhongxing Xuc4761f52009-05-09 15:18:12 +0000784 ER = cast<ElementRegion>(MR);
Zhongxing Xu5414a5c2009-06-21 13:24:24 +0000785 }
Zhongxing Xu2b1dc172009-03-11 07:43:49 +0000786
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000787 SVal Idx = ER->getIndex();
788
789 nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
790 nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R);
791
792 // Only support concrete integer indexes for now.
793 if (Base && Offset) {
Ted Kremenek610e81d2009-03-13 15:35:24 +0000794 // FIXME: For now, convert the signedness and bitwidth of offset in case
795 // they don't match. This can result from pointer arithmetic. In reality,
796 // we should figure out what are the proper semantics and implement them.
797 //
Ted Kremenek1060a3c2009-03-13 15:39:16 +0000798 // This addresses the test case test/Analysis/ptr-arith.c
799 //
Ted Kremenek610e81d2009-03-13 15:35:24 +0000800 nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(),
801 Offset->getValue()));
802 SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted);
Ted Kremenekf936f452009-05-04 06:18:28 +0000803 const MemRegion* NewER =
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000804 MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(),
805 getContext());
Zhongxing Xud91ee272009-06-23 09:02:15 +0000806 return ValMgr.makeLoc(NewER);
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000807
Ted Kremenek5dc27462009-03-03 02:51:43 +0000808 }
809
810 return UnknownVal();
Zhongxing Xu94aa6c12009-03-02 07:52:23 +0000811}
812
Ted Kremenek9af46f52009-06-16 22:36:44 +0000813//===----------------------------------------------------------------------===//
814// Loading values from regions.
815//===----------------------------------------------------------------------===//
816
Ted Kremenek67f28532009-06-17 22:02:04 +0000817SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
818
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000819 assert(!isa<UnknownVal>(L) && "location unknown");
820 assert(!isa<UndefinedVal>(L) && "location undefined");
821
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000822 // FIXME: Is this even possible? Shouldn't this be treated as a null
823 // dereference at a higher level?
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000824 if (isa<loc::ConcreteInt>(L))
825 return UndefinedVal();
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000826
Ted Kremenek67f28532009-06-17 22:02:04 +0000827 const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
Zhongxing Xua1718c72009-04-03 07:33:13 +0000828
Zhongxing Xu91844122009-05-20 09:18:48 +0000829 // FIXME: return symbolic value for these cases.
Zhongxing Xua1718c72009-04-03 07:33:13 +0000830 // Example:
831 // void f(int* p) { int x = *p; }
Zhongxing Xu91844122009-05-20 09:18:48 +0000832 // char* p = alloca();
833 // read(p);
834 // c = *p;
835 if (isa<SymbolicRegion>(MR) || isa<AllocaRegion>(MR))
Zhongxing Xua1718c72009-04-03 07:33:13 +0000836 return UnknownVal();
837
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000838 // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
839 // instead of 'Loc', and have the other Loc cases handled at a higher level.
Ted Kremenek67f28532009-06-17 22:02:04 +0000840 const TypedRegion *R = cast<TypedRegion>(MR);
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000841 assert(R && "bad region");
842
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000843 if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
844 return RetrieveField(state, FR);
845
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000846 if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
847 return RetrieveElement(state, ER);
848
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000849 // FIXME: We should eventually handle funny addressing. e.g.:
850 //
851 // int x = ...;
852 // int *p = &x;
853 // char *q = (char*) p;
854 // char c = *q; // returns the first byte of 'x'.
855 //
856 // Such funny addressing will occur due to layering of regions.
857
Zhongxing Xua82d8aa2009-05-09 03:57:34 +0000858 QualType RTy = R->getValueType(getContext());
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000859
Zhongxing Xu1038f9f2009-03-09 09:15:51 +0000860 if (RTy->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +0000861 return RetrieveStruct(state, R);
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000862
863 if (RTy->isArrayType())
Ted Kremenek67f28532009-06-17 22:02:04 +0000864 return RetrieveArray(state, R);
Zhongxing Xu3e001f32009-05-03 00:27:40 +0000865
Zhongxing Xu1038f9f2009-03-09 09:15:51 +0000866 // FIXME: handle Vector types.
867 if (RTy->isVectorType())
Ted Kremenek265a3052009-02-24 02:23:11 +0000868 return UnknownVal();
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000869
Ted Kremenek67f28532009-06-17 22:02:04 +0000870 RegionBindingsTy B = GetRegionBindings(state->getStore());
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000871 RegionBindingsTy::data_type* V = B.lookup(R);
872
873 // Check if the region has a binding.
874 if (V)
875 return *V;
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000876
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000877 // Check if the region is in killset.
Ted Kremenek67f28532009-06-17 22:02:04 +0000878 if (state->contains<RegionKills>(R))
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000879 return UnknownVal();
880
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000881 if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
882 const MemRegion *SR = IVR->getSuperRegion();
883
884 // If the super region is 'self' then return the symbol representing
885 // the value of the ivar upon entry to the method.
886 if (SR == SelfRegion) {
887 // FIXME: Do we need to handle the case where the super region
888 // has a view? We want to canonicalize the bindings.
Zhongxing Xud9b6ad62009-05-09 04:08:27 +0000889 return ValMgr.getRegionValueSymbolVal(R);
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000890 }
891
892 // Otherwise, we need a new symbol. For now return Unknown.
893 return UnknownVal();
894 }
Zhongxing Xu562c4d92009-01-23 11:22:12 +0000895
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000896 // The location does not have a bound value. This means that it has
897 // the value it had upon its creation and/or entry to the analyzed
898 // function/method. These are either symbolic values or 'undefined'.
899
900 // We treat function parameters as symbolic values.
Ted Kremenek6fd8f912009-01-22 23:43:57 +0000901 if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
902 const VarDecl *VD = VR->getDecl();
903
Ted Kremenekcec35252009-03-04 00:23:05 +0000904 if (VD == SelfDecl)
905 return loc::MemRegionVal(getSelfRegion(0));
906
907 if (isa<ParmVarDecl>(VD) || isa<ImplicitParamDecl>(VD) ||
908 VD->hasGlobalStorage()) {
Zhongxing Xud8895f62009-02-19 09:56:08 +0000909 QualType VTy = VD->getType();
910 if (Loc::IsLocType(VTy) || VTy->isIntegerType())
Zhongxing Xud9b6ad62009-05-09 04:08:27 +0000911 return ValMgr.getRegionValueSymbolVal(VR);
Zhongxing Xud8895f62009-02-19 09:56:08 +0000912 else
913 return UnknownVal();
914 }
Ted Kremenek3de2d3c2009-03-05 04:50:08 +0000915 }
Ted Kremenek265a3052009-02-24 02:23:11 +0000916
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000917 if (R->hasHeapOrStackStorage()) {
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000918 // All stack variables are considered to have undefined values
919 // upon creation. All heap allocated blocks are considered to
920 // have undefined values as well unless they are explicitly bound
921 // to specific values.
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000922 return UndefinedVal();
Ted Kremenek869fb4a2008-12-24 07:46:32 +0000923 }
924
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000925 // If the region is already cast to another type, use that type to create the
926 // symbol value.
927 if (const QualType *p = state->get<RegionCasts>(R)) {
928 QualType T = *p;
929 RTy = T->getAsPointerType()->getPointeeType();
930 }
931
Zhongxing Xuff8d2042009-03-09 09:31:22 +0000932 // All other integer values are symbolic.
933 if (Loc::IsLocType(RTy) || RTy->isIntegerType())
Zhongxing Xu88c675f2009-06-18 06:29:10 +0000934 return ValMgr.getRegionValueSymbolVal(R, RTy);
Zhongxing Xuff8d2042009-03-09 09:31:22 +0000935 else
936 return UnknownVal();
Zhongxing Xu53bcdd42008-10-21 05:29:26 +0000937}
938
Zhongxing Xuc00346f2009-06-25 05:29:39 +0000939SVal RegionStoreManager::RetrieveElement(const GRState* state,
940 const ElementRegion* R) {
941 // Check if the region has a binding.
942 RegionBindingsTy B = GetRegionBindings(state->getStore());
943 const SVal* V = B.lookup(R);
944 if (V)
945 return *V;
946
947 // Check if the region is killed.
948 if (state->contains<RegionKills>(R))
949 return UnknownVal();
950
951 // Check if the region is an element region of a string literal.
952 if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) {
953 const StringLiteral *Str = StrR->getStringLiteral();
954 SVal Idx = R->getIndex();
955 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
956 int64_t i = CI->getValue().getSExtValue();
957 char c;
958 if (i == Str->getByteLength())
959 c = '\0';
960 else
961 c = Str->getStrData()[i];
962 return ValMgr.makeIntVal(c, getContext().CharTy);
963 }
964 }
965
966 const MemRegion* SuperR = R->getSuperRegion();
967 const SVal* D = state->get<RegionDefaultValue>(SuperR);
968
969 if (D) {
970 if (D->hasConjuredSymbol())
971 return ValMgr.getRegionValueSymbolVal(R);
972 else
973 return *D;
974 }
975
976 if (R->hasHeapOrStackStorage())
977 return UndefinedVal();
978
979 QualType Ty = R->getValueType(getContext());
980
981 // If the region is already cast to another type, use that type to create the
982 // symbol value.
983 if (const QualType *p = state->get<RegionCasts>(R))
984 Ty = (*p)->getAsPointerType()->getPointeeType();
985
986 if (Loc::IsLocType(Ty) || Ty->isIntegerType())
987 return ValMgr.getRegionValueSymbolVal(R, Ty);
988 else
989 return UnknownVal();
990}
991
Zhongxing Xu490b0f02009-06-25 04:50:44 +0000992SVal RegionStoreManager::RetrieveField(const GRState* state,
993 const FieldRegion* R) {
994 QualType Ty = R->getValueType(getContext());
995
996 // Check if the region has a binding.
997 RegionBindingsTy B = GetRegionBindings(state->getStore());
998 const SVal* V = B.lookup(R);
999 if (V)
1000 return *V;
1001
1002 // Check if the region is killed.
1003 if (state->contains<RegionKills>(R))
1004 return UnknownVal();
1005
1006 const MemRegion* SuperR = R->getSuperRegion();
1007 const SVal* D = state->get<RegionDefaultValue>(SuperR);
1008 if (D) {
1009 if (D->hasConjuredSymbol())
1010 return ValMgr.getRegionValueSymbolVal(R);
1011
1012 if (D->isZeroConstant())
1013 return ValMgr.makeZeroVal(Ty);
1014
1015 if (D->isUnknown())
1016 return *D;
1017
1018 assert(0 && "Unknown default value");
1019 }
1020
1021 if (R->hasHeapOrStackStorage())
1022 return UndefinedVal();
1023
1024 // If the region is already cast to another type, use that type to create the
1025 // symbol value.
1026 if (const QualType *p = state->get<RegionCasts>(R)) {
1027 QualType tmp = *p;
1028 Ty = tmp->getAsPointerType()->getPointeeType();
1029 }
1030
1031 // All other integer values are symbolic.
1032 if (Loc::IsLocType(Ty) || Ty->isIntegerType())
1033 return ValMgr.getRegionValueSymbolVal(R, Ty);
1034 else
1035 return UnknownVal();
1036}
1037
Zhongxing Xu88c675f2009-06-18 06:29:10 +00001038SVal RegionStoreManager::RetrieveStruct(const GRState *state,
1039 const TypedRegion* R){
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001040 QualType T = R->getValueType(getContext());
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001041 assert(T->isStructureType());
1042
Zhongxing Xub7507d12009-06-11 07:27:30 +00001043 const RecordType* RT = T->getAsStructureType();
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001044 RecordDecl* RD = RT->getDecl();
1045 assert(RD->isDefinition());
1046
1047 llvm::ImmutableList<SVal> StructVal = getBasicVals().getEmptySValList();
1048
Ted Kremenek67f28532009-06-17 22:02:04 +00001049 // FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
1050 // reverse iterator, we should implement one.
Douglas Gregor6ab35242009-04-09 21:40:53 +00001051 std::vector<FieldDecl *> Fields(RD->field_begin(getContext()),
1052 RD->field_end(getContext()));
Douglas Gregor44b43212008-12-11 16:49:14 +00001053
Douglas Gregore267ff32008-12-11 20:41:00 +00001054 for (std::vector<FieldDecl *>::reverse_iterator Field = Fields.rbegin(),
1055 FieldEnd = Fields.rend();
1056 Field != FieldEnd; ++Field) {
1057 FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001058 QualType FTy = (*Field)->getType();
Ted Kremenek67f28532009-06-17 22:02:04 +00001059 SVal FieldValue = Retrieve(state, loc::MemRegionVal(FR), FTy);
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001060 StructVal = getBasicVals().consVals(FieldValue, StructVal);
1061 }
1062
Zhongxing Xud91ee272009-06-23 09:02:15 +00001063 return ValMgr.makeCompoundVal(T, StructVal);
Zhongxing Xu6e3f01c2008-10-31 07:16:08 +00001064}
1065
Ted Kremenek67f28532009-06-17 22:02:04 +00001066SVal RegionStoreManager::RetrieveArray(const GRState *state,
1067 const TypedRegion * R) {
1068
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001069 QualType T = R->getValueType(getContext());
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001070 ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
1071
1072 llvm::ImmutableList<SVal> ArrayVal = getBasicVals().getEmptySValList();
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001073 llvm::APSInt Size(CAT->getSize(), false);
Zhongxing Xu2ee52142009-05-11 12:48:56 +00001074 llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001075
1076 for (; i < Size; ++i) {
Zhongxing Xud91ee272009-06-23 09:02:15 +00001077 SVal Idx = ValMgr.makeIntVal(i);
Zhongxing Xu143b2fc2009-06-16 09:55:50 +00001078 ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R,
1079 getContext());
Ted Kremenekf936f452009-05-04 06:18:28 +00001080 QualType ETy = ER->getElementType();
Ted Kremenek67f28532009-06-17 22:02:04 +00001081 SVal ElementVal = Retrieve(state, loc::MemRegionVal(ER), ETy);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001082 ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal);
1083 }
1084
Zhongxing Xud91ee272009-06-23 09:02:15 +00001085 return ValMgr.makeCompoundVal(T, ArrayVal);
Zhongxing Xu3e001f32009-05-03 00:27:40 +00001086}
1087
Ted Kremenek9af46f52009-06-16 22:36:44 +00001088//===----------------------------------------------------------------------===//
1089// Binding values to regions.
1090//===----------------------------------------------------------------------===//
Zhongxing Xu17892752008-10-08 02:50:44 +00001091
Zhongxing Xu9c9ca082008-12-16 02:36:30 +00001092Store RegionStoreManager::Remove(Store store, Loc L) {
Ted Kremenek0964a062009-01-21 06:57:53 +00001093 const MemRegion* R = 0;
1094
1095 if (isa<loc::MemRegionVal>(L))
1096 R = cast<loc::MemRegionVal>(L).getRegion();
Ted Kremenek0964a062009-01-21 06:57:53 +00001097
1098 if (R) {
1099 RegionBindingsTy B = GetRegionBindings(store);
1100 return RBFactory.Remove(B, R).getRoot();
1101 }
1102
1103 return store;
Zhongxing Xu9c9ca082008-12-16 02:36:30 +00001104}
1105
Ted Kremenek67f28532009-06-17 22:02:04 +00001106const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
Ted Kremenek9af46f52009-06-16 22:36:44 +00001107 // If we get here, the location should be a region.
1108 const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
Ted Kremenek9af46f52009-06-16 22:36:44 +00001109
1110 // Check if the region is a struct region.
1111 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
1112 if (TR->getValueType(getContext())->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001113 return BindStruct(state, TR, V);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001114
Ted Kremenek67f28532009-06-17 22:02:04 +00001115 RegionBindingsTy B = GetRegionBindings(state->getStore());
Ted Kremenek9af46f52009-06-16 22:36:44 +00001116
1117 if (V.isUnknown()) {
Ted Kremenek67f28532009-06-17 22:02:04 +00001118 B = RBFactory.Remove(B, R); // Remove the binding.
1119 state = state->add<RegionKills>(R); // Add the region to the killset.
Ted Kremenek9af46f52009-06-16 22:36:44 +00001120 }
1121 else
Ted Kremenek67f28532009-06-17 22:02:04 +00001122 B = RBFactory.Add(B, R, V);
Ted Kremenek9af46f52009-06-16 22:36:44 +00001123
Ted Kremenek67f28532009-06-17 22:02:04 +00001124 return state->makeWithStore(B.getRoot());
Ted Kremenek9af46f52009-06-16 22:36:44 +00001125}
1126
Ted Kremenek67f28532009-06-17 22:02:04 +00001127const GRState *RegionStoreManager::BindDecl(const GRState *state,
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001128 const VarDecl* VD, SVal InitVal) {
Zhongxing Xua4f28ff2008-11-13 08:41:36 +00001129
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001130 QualType T = VD->getType();
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001131 VarRegion* VR = MRMgr.getVarRegion(VD);
Zhongxing Xuf0dfa8d2008-10-31 08:10:01 +00001132
Ted Kremenek0964a062009-01-21 06:57:53 +00001133 if (T->isArrayType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001134 return BindArray(state, VR, InitVal);
Ted Kremenek0964a062009-01-21 06:57:53 +00001135 if (T->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001136 return BindStruct(state, VR, InitVal);
Zhongxing Xud463d442008-11-02 12:13:30 +00001137
Zhongxing Xud91ee272009-06-23 09:02:15 +00001138 return Bind(state, ValMgr.makeLoc(VR), InitVal);
Zhongxing Xu17892752008-10-08 02:50:44 +00001139}
Zhongxing Xu53bcdd42008-10-21 05:29:26 +00001140
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001141// FIXME: this method should be merged into Bind().
Ted Kremenek67f28532009-06-17 22:02:04 +00001142const GRState *
1143RegionStoreManager::BindCompoundLiteral(const GRState *state,
1144 const CompoundLiteralExpr* CL,
1145 SVal V) {
1146
Zhongxing Xuf22679e2008-11-07 10:38:33 +00001147 CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL);
Ted Kremenek67f28532009-06-17 22:02:04 +00001148 return Bind(state, loc::MemRegionVal(R), V);
Zhongxing Xuf22679e2008-11-07 10:38:33 +00001149}
1150
Ted Kremenek67f28532009-06-17 22:02:04 +00001151const GRState *RegionStoreManager::BindArray(const GRState *state,
1152 const TypedRegion* R,
1153 SVal Init) {
1154
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001155 QualType T = R->getValueType(getContext());
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001156 ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001157 QualType ElementTy = CAT->getElementType();
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001158
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001159 llvm::APSInt Size(CAT->getSize(), false);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001160 llvm::APSInt i(llvm::APInt::getNullValue(Size.getBitWidth()), false);
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001161
1162 // Check if the init expr is a StringLiteral.
1163 if (isa<loc::MemRegionVal>(Init)) {
1164 const MemRegion* InitR = cast<loc::MemRegionVal>(Init).getRegion();
1165 const StringLiteral* S = cast<StringRegion>(InitR)->getStringLiteral();
1166 const char* str = S->getStrData();
1167 unsigned len = S->getByteLength();
1168 unsigned j = 0;
1169
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001170 // Copy bytes from the string literal into the target array. Trailing bytes
1171 // in the array that are not covered by the string literal are initialized
1172 // to zero.
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001173 for (; i < Size; ++i, ++j) {
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001174 if (j >= len)
1175 break;
1176
Zhongxing Xu3038c5a2009-06-23 06:13:19 +00001177 SVal Idx = ValMgr.makeIntVal(i);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001178 ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx,R,getContext());
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001179
Zhongxing Xud91ee272009-06-23 09:02:15 +00001180 SVal V = ValMgr.makeIntVal(str[j], sizeof(char)*8, true);
Ted Kremenek67f28532009-06-17 22:02:04 +00001181 state = Bind(state, loc::MemRegionVal(ER), V);
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001182 }
1183
Ted Kremenek67f28532009-06-17 22:02:04 +00001184 return state;
Zhongxing Xu6987c7b2008-11-30 05:49:49 +00001185 }
1186
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001187 nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001188 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
1189
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001190 for (; i < Size; ++i, ++VI) {
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001191 // The init list might be shorter than the array length.
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001192 if (VI == VE)
1193 break;
1194
Zhongxing Xu3038c5a2009-06-23 06:13:19 +00001195 SVal Idx = ValMgr.makeIntVal(i);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001196 ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx, R, getContext());
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001197
1198 if (CAT->getElementType()->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001199 state = BindStruct(state, ER, *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001200 else
Zhongxing Xud91ee272009-06-23 09:02:15 +00001201 state = Bind(state, ValMgr.makeLoc(ER), *VI);
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001202 }
1203
Zhongxing Xue3a765f2009-06-24 00:56:31 +00001204 // If the init list is shorter than the array length, set the array default
1205 // value.
1206 if (i < Size) {
1207 if (ElementTy->isIntegerType()) {
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001208 SVal V = ValMgr.makeZeroVal(ElementTy);
Zhongxing Xue3a765f2009-06-24 00:56:31 +00001209 state = setDefaultValue(state, R, V);
Zhongxing Xu087d6c22009-06-23 05:23:38 +00001210 }
1211 }
1212
Ted Kremenek67f28532009-06-17 22:02:04 +00001213 return state;
Zhongxing Xu1a12a0e2008-10-31 10:24:47 +00001214}
1215
Ted Kremenek67f28532009-06-17 22:02:04 +00001216const GRState *
1217RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,
1218 SVal V) {
1219
1220 if (!Features.supportsFields())
1221 return state;
1222
Zhongxing Xua82d8aa2009-05-09 03:57:34 +00001223 QualType T = R->getValueType(getContext());
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001224 assert(T->isStructureType());
1225
Zhongxing Xub13ecdb2009-03-12 03:45:35 +00001226 const RecordType* RT = T->getAsRecordType();
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001227 RecordDecl* RD = RT->getDecl();
Zhongxing Xuc45a8252009-03-11 09:07:35 +00001228
1229 if (!RD->isDefinition())
Ted Kremenek67f28532009-06-17 22:02:04 +00001230 return state;
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001231
Ted Kremenek67f28532009-06-17 22:02:04 +00001232 // We may get non-CompoundVal accidentally due to imprecise cast logic.
1233 // Ignore them and kill the field values.
1234 if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
1235 return KillStruct(state, R);
Zhongxing Xu3f6978a2009-06-11 09:11:27 +00001236
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001237 nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001238 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001239
1240 RecordDecl::field_iterator FI, FE;
1241
1242 for (FI = RD->field_begin(getContext()), FE = RD->field_end(getContext());
Ted Kremenek67f28532009-06-17 22:02:04 +00001243 FI != FE; ++FI, ++VI) {
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001244
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001245 if (VI == VE)
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001246 break;
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001247
Zhongxing Xuaf0a8442008-10-31 10:53:01 +00001248 QualType FTy = (*FI)->getType();
1249 FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
1250
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001251 if (Loc::IsLocType(FTy) || FTy->isIntegerType())
Zhongxing Xud91ee272009-06-23 09:02:15 +00001252 state = Bind(state, ValMgr.makeLoc(FR), *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001253 else if (FTy->isArrayType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001254 state = BindArray(state, FR, *VI);
Zhongxing Xu4193eca2008-12-20 06:32:12 +00001255 else if (FTy->isStructureType())
Ted Kremenek67f28532009-06-17 22:02:04 +00001256 state = BindStruct(state, FR, *VI);
Zhongxing Xua82512a2008-10-24 08:42:28 +00001257 }
1258
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001259 // There may be fewer values in the initialize list than the fields of struct.
Zhongxing Xu490b0f02009-06-25 04:50:44 +00001260 if (FI != FE)
1261 state = setDefaultValue(state, R, ValMgr.makeIntVal(0, false));
Zhongxing Xudbdf2192009-06-23 05:43:16 +00001262
Ted Kremenek67f28532009-06-17 22:02:04 +00001263 return state;
Zhongxing Xuc3a05992008-11-19 11:06:24 +00001264}
1265
Ted Kremenek67f28532009-06-17 22:02:04 +00001266const GRState *RegionStoreManager::KillStruct(const GRState *state,
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001267 const TypedRegion* R){
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001268
Ted Kremenek67f28532009-06-17 22:02:04 +00001269 // (1) Kill the struct region because it is assigned "unknown".
1270 // (2) Set the default value of the struct region to "unknown".
1271 state = state->add<RegionKills>(R)->set<RegionDefaultValue>(R, UnknownVal());
1272 Store store = state->getStore();
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001273 RegionBindingsTy B = GetRegionBindings(store);
1274
1275 // Remove all bindings for the subregions of the struct.
1276 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
Ted Kremenek67f28532009-06-17 22:02:04 +00001277 const MemRegion* R = I.getKey();
1278 if (const SubRegion* subRegion = dyn_cast<SubRegion>(R))
1279 if (subRegion->isSubRegionOf(R))
Zhongxing Xud91ee272009-06-23 09:02:15 +00001280 store = Remove(store, ValMgr.makeLoc(subRegion));
Zhongxing Xu9c2a3db2009-01-13 03:07:41 +00001281 // FIXME: Maybe we should also remove the bindings for the "views" of the
1282 // subregions.
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001283 }
1284
Ted Kremenek67f28532009-06-17 22:02:04 +00001285 return state->makeWithStore(store);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001286}
1287
Ted Kremenek9af46f52009-06-16 22:36:44 +00001288//===----------------------------------------------------------------------===//
1289// Region views.
1290//===----------------------------------------------------------------------===//
1291
Ted Kremenek67f28532009-06-17 22:02:04 +00001292const GRState *RegionStoreManager::AddRegionView(const GRState *state,
1293 const MemRegion* View,
1294 const MemRegion* Base) {
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001295
1296 // First, retrieve the region view of the base region.
Ted Kremenek67f28532009-06-17 22:02:04 +00001297 const RegionViews* d = state->get<RegionViewMap>(Base);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001298 RegionViews L = d ? *d : RVFactory.GetEmptySet();
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001299
1300 // Now add View to the region view.
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001301 L = RVFactory.Add(L, View);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001302
1303 // Create a new state with the new region view.
Ted Kremenek67f28532009-06-17 22:02:04 +00001304 return state->set<RegionViewMap>(Base, L);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +00001305}
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001306
Ted Kremenek67f28532009-06-17 22:02:04 +00001307const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
1308 const MemRegion* View,
1309 const MemRegion* Base) {
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001310 // Retrieve the region view of the base region.
Ted Kremenek67f28532009-06-17 22:02:04 +00001311 const RegionViews* d = state->get<RegionViewMap>(Base);
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001312
1313 // If the base region has no view, return.
1314 if (!d)
Ted Kremenek67f28532009-06-17 22:02:04 +00001315 return state;
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001316
1317 // Remove the view.
Ted Kremenek67f28532009-06-17 22:02:04 +00001318 return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View));
Zhongxing Xu5834ed62009-01-13 01:49:57 +00001319}
Zhongxing Xu20794942009-05-06 08:33:50 +00001320
Zhongxing Xu88c675f2009-06-18 06:29:10 +00001321const GRState *RegionStoreManager::setCastType(const GRState *state,
1322 const MemRegion* R, QualType T) {
Ted Kremenek67f28532009-06-17 22:02:04 +00001323 return state->set<RegionCasts>(R, T);
Zhongxing Xu20794942009-05-06 08:33:50 +00001324}
Zhongxing Xu264e9372009-05-12 10:10:00 +00001325
Ted Kremenek67f28532009-06-17 22:02:04 +00001326const GRState *RegionStoreManager::setDefaultValue(const GRState *state,
1327 const MemRegion* R, SVal V) {
1328 return state->set<RegionDefaultValue>(R, V);
Zhongxing Xu264e9372009-05-12 10:10:00 +00001329}
Ted Kremenek9af46f52009-06-16 22:36:44 +00001330
1331//===----------------------------------------------------------------------===//
1332// State pruning.
1333//===----------------------------------------------------------------------===//
1334
1335static void UpdateLiveSymbols(SVal X, SymbolReaper& SymReaper) {
1336 if (loc::MemRegionVal *XR = dyn_cast<loc::MemRegionVal>(&X)) {
1337 const MemRegion *R = XR->getRegion();
1338
1339 while (R) {
1340 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1341 SymReaper.markLive(SR->getSymbol());
1342 return;
1343 }
1344
1345 if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
1346 R = SR->getSuperRegion();
1347 continue;
1348 }
1349
1350 break;
1351 }
1352
1353 return;
1354 }
1355
1356 for (SVal::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();SI!=SE;++SI)
1357 SymReaper.markLive(*SI);
1358}
1359
Ted Kremenek67f28532009-06-17 22:02:04 +00001360Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
Ted Kremenek9af46f52009-06-16 22:36:44 +00001361 SymbolReaper& SymReaper,
1362 llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
Ted Kremenek67f28532009-06-17 22:02:04 +00001363{
Ted Kremenek9af46f52009-06-16 22:36:44 +00001364 Store store = state->getStore();
1365 RegionBindingsTy B = GetRegionBindings(store);
1366
1367 // Lazily constructed backmap from MemRegions to SubRegions.
1368 typedef llvm::ImmutableSet<const MemRegion*> SubRegionsTy;
1369 typedef llvm::ImmutableMap<const MemRegion*, SubRegionsTy> SubRegionsMapTy;
1370
1371 // FIXME: As a future optimization we can modifiy BumpPtrAllocator to have
1372 // the ability to reuse memory. This way we can keep TmpAlloc around as
1373 // an instance variable of RegionStoreManager (avoiding repeated malloc
1374 // overhead).
1375 llvm::BumpPtrAllocator TmpAlloc;
1376
1377 // Factory objects.
1378 SubRegionsMapTy::Factory SubRegMapF(TmpAlloc);
1379 SubRegionsTy::Factory SubRegF(TmpAlloc);
1380
1381 // The backmap from regions to subregions.
1382 SubRegionsMapTy SubRegMap = SubRegMapF.GetEmptyMap();
1383
1384 // Do a pass over the regions in the store. For VarRegions we check if
1385 // the variable is still live and if so add it to the list of live roots.
Ted Kremenek67f28532009-06-17 22:02:04 +00001386 // For other regions we populate our region backmap.
Ted Kremenek9af46f52009-06-16 22:36:44 +00001387 llvm::SmallVector<const MemRegion*, 10> IntermediateRoots;
1388
1389 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1390 IntermediateRoots.push_back(I.getKey());
1391 }
1392
1393 while (!IntermediateRoots.empty()) {
1394 const MemRegion* R = IntermediateRoots.back();
1395 IntermediateRoots.pop_back();
1396
1397 if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
1398 if (SymReaper.isLive(Loc, VR->getDecl()))
1399 RegionRoots.push_back(VR); // This is a live "root".
1400 }
1401 else if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
1402 if (SymReaper.isLive(SR->getSymbol()))
1403 RegionRoots.push_back(SR);
1404 }
1405 else {
1406 // Get the super region for R.
1407 const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
1408
1409 // Get the current set of subregions for SuperR.
1410 const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
1411 SubRegionsTy SRs = SRptr ? *SRptr : SubRegF.GetEmptySet();
1412
1413 // Add R to the subregions of SuperR.
1414 SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SRs, R));
1415
1416 // Super region may be VarRegion or subregion of another VarRegion. Add it
1417 // to the work list.
1418 if (isa<SubRegion>(SuperR))
1419 IntermediateRoots.push_back(SuperR);
1420 }
1421 }
1422
1423 // Process the worklist of RegionRoots. This performs a "mark-and-sweep"
1424 // of the store. We want to find all live symbols and dead regions.
1425 llvm::SmallPtrSet<const MemRegion*, 10> Marked;
1426
1427 while (!RegionRoots.empty()) {
1428 // Dequeue the next region on the worklist.
1429 const MemRegion* R = RegionRoots.back();
1430 RegionRoots.pop_back();
1431
1432 // Check if we have already processed this region.
1433 if (Marked.count(R)) continue;
1434
1435 // Mark this region as processed. This is needed for termination in case
1436 // a region is referenced more than once.
1437 Marked.insert(R);
1438
1439 // Mark the symbol for any live SymbolicRegion as "live". This means we
1440 // should continue to track that symbol.
1441 if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
1442 SymReaper.markLive(SymR->getSymbol());
1443
1444 // Get the data binding for R (if any).
1445 RegionBindingsTy::data_type* Xptr = B.lookup(R);
1446 if (Xptr) {
1447 SVal X = *Xptr;
1448 UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
1449
1450 // If X is a region, then add it the RegionRoots.
1451 if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X))
1452 RegionRoots.push_back(RegionX->getRegion());
1453 }
1454
1455 // Get the subregions of R. These are RegionRoots as well since they
1456 // represent values that are also bound to R.
1457 const SubRegionsTy* SRptr = SubRegMap.lookup(R);
1458 if (!SRptr) continue;
1459 SubRegionsTy SR = *SRptr;
1460
1461 for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)
1462 RegionRoots.push_back(*I);
1463 }
1464
1465 // We have now scanned the store, marking reachable regions and symbols
1466 // as live. We now remove all the regions that are dead from the store
1467 // as well as update DSymbols with the set symbols that are now dead.
1468 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1469 const MemRegion* R = I.getKey();
1470
1471 // If this region live? Is so, none of its symbols are dead.
1472 if (Marked.count(R))
1473 continue;
1474
1475 // Remove this dead region from the store.
Zhongxing Xud91ee272009-06-23 09:02:15 +00001476 store = Remove(store, ValMgr.makeLoc(R));
Ted Kremenek9af46f52009-06-16 22:36:44 +00001477
1478 // Mark all non-live symbols that this region references as dead.
1479 if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
1480 SymReaper.maybeDead(SymR->getSymbol());
1481
1482 SVal X = I.getData();
1483 SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
1484 for (; SI != SE; ++SI) SymReaper.maybeDead(*SI);
1485 }
1486
1487 return store;
1488}
1489
1490//===----------------------------------------------------------------------===//
1491// Utility methods.
1492//===----------------------------------------------------------------------===//
1493
Ted Kremenek53ba0b62009-06-24 23:06:47 +00001494void RegionStoreManager::print(Store store, llvm::raw_ostream& OS,
Ted Kremenek9af46f52009-06-16 22:36:44 +00001495 const char* nl, const char *sep) {
Ted Kremenek9af46f52009-06-16 22:36:44 +00001496 RegionBindingsTy B = GetRegionBindings(store);
1497 OS << "Store:" << nl;
1498
1499 for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1500 OS << ' '; I.getKey()->print(OS); OS << " : ";
1501 I.getData().print(OS); OS << nl;
1502 }
1503}