blob: 9cfeb7ae2b5cbbb6246c40dee7df4c23a47d3759 [file] [log] [blame]
Ted Kremenek9e240492008-10-04 05:50:14 +00001//== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
11// partially-typed abstraction of memory useful for path-sensitive dataflow
12// analyses.
13//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek1309f9a2010-01-25 04:41:41 +000016#include "clang/Checker/PathSensitive/MemRegion.h"
Jordy Rose32f26562010-07-04 00:00:41 +000017#include "clang/Checker/PathSensitive/ValueManager.h"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000018#include "clang/Analysis/AnalysisContext.h"
19#include "clang/Analysis/Support/BumpVector.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000020#include "clang/AST/CharUnits.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000021#include "llvm/Support/raw_ostream.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000022
23using namespace clang;
24
Ted Kremenek25010132009-06-22 23:13:13 +000025//===----------------------------------------------------------------------===//
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000026// MemRegion Construction.
27//===----------------------------------------------------------------------===//
28
29template<typename RegionTy> struct MemRegionManagerTrait;
30
31template <typename RegionTy, typename A1>
32RegionTy* MemRegionManager::getRegion(const A1 a1) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000033
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000034 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
35 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000036
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000037 llvm::FoldingSetNodeID ID;
38 RegionTy::ProfileRegion(ID, a1, superRegion);
39 void* InsertPos;
40 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
41 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000042
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000043 if (!R) {
44 R = (RegionTy*) A.Allocate<RegionTy>();
45 new (R) RegionTy(a1, superRegion);
46 Regions.InsertNode(R, InsertPos);
47 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000048
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000049 return R;
50}
51
52template <typename RegionTy, typename A1>
53RegionTy* MemRegionManager::getSubRegion(const A1 a1,
54 const MemRegion *superRegion) {
55 llvm::FoldingSetNodeID ID;
56 RegionTy::ProfileRegion(ID, a1, superRegion);
57 void* InsertPos;
58 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
59 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000060
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000061 if (!R) {
62 R = (RegionTy*) A.Allocate<RegionTy>();
63 new (R) RegionTy(a1, superRegion);
64 Regions.InsertNode(R, InsertPos);
65 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000066
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000067 return R;
68}
69
70template <typename RegionTy, typename A1, typename A2>
71RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000072
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000073 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
74 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000075
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000076 llvm::FoldingSetNodeID ID;
77 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
78 void* InsertPos;
79 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
80 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000081
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000082 if (!R) {
83 R = (RegionTy*) A.Allocate<RegionTy>();
84 new (R) RegionTy(a1, a2, superRegion);
85 Regions.InsertNode(R, InsertPos);
86 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000087
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000088 return R;
89}
90
91template <typename RegionTy, typename A1, typename A2>
92RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
93 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000094
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000095 llvm::FoldingSetNodeID ID;
96 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
97 void* InsertPos;
98 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
99 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000100
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000101 if (!R) {
102 R = (RegionTy*) A.Allocate<RegionTy>();
103 new (R) RegionTy(a1, a2, superRegion);
104 Regions.InsertNode(R, InsertPos);
105 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000106
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000107 return R;
108}
109
Ted Kremenek67d12872009-12-07 22:05:27 +0000110template <typename RegionTy, typename A1, typename A2, typename A3>
111RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
112 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000113
Ted Kremenek67d12872009-12-07 22:05:27 +0000114 llvm::FoldingSetNodeID ID;
115 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
116 void* InsertPos;
117 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
118 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000119
Ted Kremenek67d12872009-12-07 22:05:27 +0000120 if (!R) {
121 R = (RegionTy*) A.Allocate<RegionTy>();
122 new (R) RegionTy(a1, a2, a3, superRegion);
123 Regions.InsertNode(R, InsertPos);
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000124 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000125
Ted Kremenek67d12872009-12-07 22:05:27 +0000126 return R;
127}
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000128
129//===----------------------------------------------------------------------===//
Ted Kremenek42400962009-11-26 02:34:36 +0000130// Object destruction.
Ted Kremenek25010132009-06-22 23:13:13 +0000131//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000132
133MemRegion::~MemRegion() {}
134
Ted Kremenek42400962009-11-26 02:34:36 +0000135MemRegionManager::~MemRegionManager() {
136 // All regions and their data are BumpPtrAllocated. No need to call
137 // their destructors.
138}
139
140//===----------------------------------------------------------------------===//
141// Basic methods.
142//===----------------------------------------------------------------------===//
143
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +0000144bool SubRegion::isSubRegionOf(const MemRegion* R) const {
145 const MemRegion* r = getSuperRegion();
146 while (r != 0) {
147 if (r == R)
148 return true;
149 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
150 r = sr->getSuperRegion();
151 else
152 break;
153 }
154 return false;
155}
156
Ted Kremeneka43484a2009-06-23 00:46:41 +0000157MemRegionManager* SubRegion::getMemRegionManager() const {
158 const SubRegion* r = this;
159 do {
160 const MemRegion *superRegion = r->getSuperRegion();
161 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
162 r = sr;
163 continue;
164 }
165 return superRegion->getMemRegionManager();
166 } while (1);
167}
168
Ted Kremenek5348f942009-12-14 22:15:06 +0000169const StackFrameContext *VarRegion::getStackFrame() const {
170 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
171 return SSR ? SSR->getStackFrame() : NULL;
172}
173
174//===----------------------------------------------------------------------===//
Jordy Rose32f26562010-07-04 00:00:41 +0000175// Region extents.
176//===----------------------------------------------------------------------===//
177
178DefinedOrUnknownSVal DeclRegion::getExtent(ValueManager& ValMgr) const {
179 ASTContext& Ctx = ValMgr.getContext();
180 QualType T = getDesugaredValueType(Ctx);
181
Jordy Rose52e04c52010-07-05 00:50:15 +0000182 if (isa<VariableArrayType>(T))
183 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
184 if (isa<IncompleteArrayType>(T))
Jordy Rose32f26562010-07-04 00:00:41 +0000185 return UnknownVal();
186
187 CharUnits Size = Ctx.getTypeSizeInChars(T);
188 QualType SizeTy = Ctx.getSizeType();
189 return ValMgr.makeIntVal(Size.getQuantity(), SizeTy);
190}
191
192DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const {
193 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(ValMgr);
194
195 // A zero-length array at the end of a struct often stands for dynamically-
196 // allocated extra memory.
197 if (Extent.isZeroConstant()) {
198 ASTContext& Ctx = ValMgr.getContext();
199 QualType T = getDesugaredValueType(Ctx);
200
201 if (isa<ConstantArrayType>(T))
202 return UnknownVal();
203 }
204
205 return Extent;
206}
207
208DefinedOrUnknownSVal AllocaRegion::getExtent(ValueManager& ValMgr) const {
209 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
210}
211
212DefinedOrUnknownSVal SymbolicRegion::getExtent(ValueManager& ValMgr) const {
213 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
214}
215
216DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const {
217 QualType SizeTy = ValMgr.getContext().getSizeType();
218 return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy);
219}
220
221//===----------------------------------------------------------------------===//
Ted Kremenek5348f942009-12-14 22:15:06 +0000222// FoldingSet profiling.
223//===----------------------------------------------------------------------===//
224
Ted Kremenek9e240492008-10-04 05:50:14 +0000225void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
226 ID.AddInteger((unsigned)getKind());
227}
228
Ted Kremenek67d12872009-12-07 22:05:27 +0000229void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
230 ID.AddInteger((unsigned)getKind());
231 ID.AddPointer(getStackFrame());
232}
233
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000234void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
235 ID.AddInteger((unsigned)getKind());
236 ID.AddPointer(getCodeRegion());
237}
238
Mike Stump1eb44332009-09-09 15:08:12 +0000239void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
240 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000241 const MemRegion* superRegion) {
242 ID.AddInteger((unsigned) StringRegionKind);
243 ID.AddPointer(Str);
244 ID.AddPointer(superRegion);
245}
246
Ted Kremenek7090ae12008-11-02 00:34:33 +0000247void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000248 const Expr* Ex, unsigned cnt,
249 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000250 ID.AddInteger((unsigned) AllocaRegionKind);
251 ID.AddPointer(Ex);
252 ID.AddInteger(cnt);
253}
254
255void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000256 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000257}
258
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000259void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
260 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
261}
262
263void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
264 const CompoundLiteralExpr* CL,
265 const MemRegion* superRegion) {
266 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
267 ID.AddPointer(CL);
268 ID.AddPointer(superRegion);
269}
270
Ted Kremenekde0d2632010-01-05 02:18:06 +0000271void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
272 const PointerType *PT,
273 const MemRegion *sRegion) {
274 ID.AddInteger((unsigned) CXXThisRegionKind);
275 ID.AddPointer(PT);
276 ID.AddPointer(sRegion);
277}
278
279void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
280 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
281}
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000282
Ted Kremenek9e240492008-10-04 05:50:14 +0000283void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
284 const MemRegion* superRegion, Kind k) {
285 ID.AddInteger((unsigned) k);
286 ID.AddPointer(D);
287 ID.AddPointer(superRegion);
288}
289
290void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
291 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
292}
293
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000294void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000295 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000296}
297
Ted Kremenek25010132009-06-22 23:13:13 +0000298void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
299 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000300 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000301 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000302 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000303}
304
305void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000306 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000307}
308
Ted Kremenekf936f452009-05-04 06:18:28 +0000309void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000310 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000311 const MemRegion* superRegion) {
312 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000313 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000314 ID.AddPointer(superRegion);
315 Idx.Profile(ID);
316}
317
318void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000319 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000320}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000321
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000322void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
323 const FunctionDecl *FD,
324 const MemRegion*) {
325 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000326 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000327}
328
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000329void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
330 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
331}
332
333void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000334 const BlockDecl *BD, CanQualType,
335 const AnalysisContext *AC,
336 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000337 ID.AddInteger(MemRegion::BlockTextRegionKind);
338 ID.AddPointer(BD);
339}
340
341void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000342 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000343}
344
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000345void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
346 const BlockTextRegion *BC,
347 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000348 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000349 ID.AddInteger(MemRegion::BlockDataRegionKind);
350 ID.AddPointer(BC);
351 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000352 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000353}
354
355void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000356 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000357}
358
Zhongxing Xubb141212009-12-16 11:27:52 +0000359void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000360 Expr const *Ex,
Zhongxing Xubb141212009-12-16 11:27:52 +0000361 const MemRegion *sReg) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000362 ID.AddPointer(Ex);
Zhongxing Xubb141212009-12-16 11:27:52 +0000363 ID.AddPointer(sReg);
364}
365
366void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000367 ProfileRegion(ID, Ex, getSuperRegion());
Zhongxing Xubb141212009-12-16 11:27:52 +0000368}
369
Zhongxing Xu026c6632009-02-05 06:57:29 +0000370//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000371// Region pretty-printing.
372//===----------------------------------------------------------------------===//
373
Ted Kremenek8800ad42009-07-13 23:31:04 +0000374void MemRegion::dump() const {
375 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000376}
377
Ted Kremenek9e240492008-10-04 05:50:14 +0000378std::string MemRegion::getString() const {
379 std::string s;
380 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000381 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000382 return os.str();
383}
384
Ted Kremenek8800ad42009-07-13 23:31:04 +0000385void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000386 os << "<Unknown Region>";
387}
388
Ted Kremenek8800ad42009-07-13 23:31:04 +0000389void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000390 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
391}
392
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000393void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000394 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000395}
396
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000397void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000398 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000399}
400
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000401void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
402 os << "block_data{" << BC << '}';
403}
404
Ted Kremenek8800ad42009-07-13 23:31:04 +0000405void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000406 // FIXME: More elaborate pretty-printing.
407 os << "{ " << (void*) CL << " }";
408}
409
Ted Kremenekde0d2632010-01-05 02:18:06 +0000410void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
411 os << "this";
412}
413
Ted Kremenek8800ad42009-07-13 23:31:04 +0000414void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000415 os << "element{" << superRegion << ','
416 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000417}
418
Ted Kremenek8800ad42009-07-13 23:31:04 +0000419void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000420 os << superRegion << "->" << getDecl();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000421}
422
Ted Kremenekfa87d812010-07-06 23:37:21 +0000423void NonStaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
424 os << "NonStaticGlobalSpaceRegion";
425}
426
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000427void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000428 os << "ivar{" << superRegion << ',' << getDecl() << '}';
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000429}
430
Mike Stump1eb44332009-09-09 15:08:12 +0000431void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000432 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000433}
434
Ted Kremenek8800ad42009-07-13 23:31:04 +0000435void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000436 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000437}
438
Ted Kremenek8800ad42009-07-13 23:31:04 +0000439void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000440 os << cast<VarDecl>(D);
Ted Kremenek9e240492008-10-04 05:50:14 +0000441}
442
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000443void RegionRawOffset::dump() const {
444 dumpToStream(llvm::errs());
445}
446
447void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
448 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
449}
450
Ted Kremenekfa87d812010-07-06 23:37:21 +0000451void StaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
452 os << "StaticGlobalsMemSpace{" << CR << '}';
453}
454
Ted Kremenek9e240492008-10-04 05:50:14 +0000455//===----------------------------------------------------------------------===//
456// MemRegionManager methods.
457//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000458
Ted Kremenek67d12872009-12-07 22:05:27 +0000459template <typename REG>
460const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000461 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000462 region = (REG*) A.Allocate<REG>();
463 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000464 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000465
Ted Kremenek9e240492008-10-04 05:50:14 +0000466 return region;
467}
468
Ted Kremenek67d12872009-12-07 22:05:27 +0000469template <typename REG, typename ARG>
470const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
471 if (!region) {
472 region = (REG*) A.Allocate<REG>();
473 new (region) REG(this, a);
474 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000475
Ted Kremenek67d12872009-12-07 22:05:27 +0000476 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000477}
478
Ted Kremenek67d12872009-12-07 22:05:27 +0000479const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000480MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
481 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000482 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
483
484 if (R)
485 return R;
486
487 R = A.Allocate<StackLocalsSpaceRegion>();
488 new (R) StackLocalsSpaceRegion(this, STC);
489 return R;
Ted Kremenekd05552a2009-07-02 18:14:59 +0000490}
491
Ted Kremenek67d12872009-12-07 22:05:27 +0000492const StackArgumentsSpaceRegion *
493MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000494 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000495 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
496
497 if (R)
498 return R;
499
500 R = A.Allocate<StackArgumentsSpaceRegion>();
501 new (R) StackArgumentsSpaceRegion(this, STC);
502 return R;
Ted Kremenek67d12872009-12-07 22:05:27 +0000503}
504
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000505const GlobalsSpaceRegion
506*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) {
507 if (!CR)
508 return LazyAllocate(globals);
509
510 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
511 if (R)
512 return R;
513
514 R = A.Allocate<StaticGlobalSpaceRegion>();
515 new (R) StaticGlobalSpaceRegion(this, CR);
516 return R;
Ted Kremenek9e240492008-10-04 05:50:14 +0000517}
518
Ted Kremenek67d12872009-12-07 22:05:27 +0000519const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000520 return LazyAllocate(heap);
521}
522
Ted Kremenekb48ad642009-12-04 00:26:31 +0000523const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000524 return LazyAllocate(unknown);
525}
526
Ted Kremenekb48ad642009-12-04 00:26:31 +0000527const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000528 return LazyAllocate(code);
529}
530
Ted Kremenek25010132009-06-22 23:13:13 +0000531//===----------------------------------------------------------------------===//
532// Constructing regions.
533//===----------------------------------------------------------------------===//
534
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000535const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
Ted Kremenek67d12872009-12-07 22:05:27 +0000536 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000537}
538
Ted Kremenekb48ad642009-12-04 00:26:31 +0000539const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
540 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000541 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000542
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000543 if (D->hasGlobalStorage() && !D->isStaticLocal())
544 sReg = getGlobalsRegion();
545 else {
Ted Kremenek67d12872009-12-07 22:05:27 +0000546 // FIXME: Once we implement scope handling, we will need to properly lookup
547 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000548 const DeclContext *DC = D->getDeclContext();
549 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000550
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000551 if (!STC)
552 sReg = getUnknownRegion();
553 else {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000554 if (D->hasLocalStorage()) {
555 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
556 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
557 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
558 }
559 else {
560 assert(D->isStaticLocal());
561 const Decl *D = STC->getDecl();
562 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
563 sReg = getGlobalsRegion(getFunctionTextRegion(FD));
564 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
565 const BlockTextRegion *BTR =
566 getBlockTextRegion(BD,
567 C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
568 STC->getAnalysisContext());
569 sReg = getGlobalsRegion(BTR);
570 }
571 else {
572 // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now
573 // just use the main global memspace.
574 sReg = getGlobalsRegion();
575 }
576 }
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000577 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000578 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000579
Ted Kremenek67d12872009-12-07 22:05:27 +0000580 return getSubRegion<VarRegion>(D, sReg);
581}
582
583const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
584 const MemRegion *superR) {
585 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000586}
587
Ted Kremenekb48ad642009-12-04 00:26:31 +0000588const BlockDataRegion *
589MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
590 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000591 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000592
593 if (LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000594 // FIXME: Once we implement scope handling, we want the parent region
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000595 // to be the scope.
Ted Kremenek67d12872009-12-07 22:05:27 +0000596 const StackFrameContext *STC = LC->getCurrentStackFrame();
597 assert(STC);
598 sReg = getStackLocalsRegion(STC);
599 }
600 else {
601 // We allow 'LC' to be NULL for cases where want BlockDataRegions
602 // without context-sensitivity.
603 sReg = getUnknownRegion();
604 }
605
606 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000607}
608
Ted Kremenekb48ad642009-12-04 00:26:31 +0000609const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000610MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
611 const LocationContext *LC) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000612
Ted Kremenek67d12872009-12-07 22:05:27 +0000613 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000614
Ted Kremenek67d12872009-12-07 22:05:27 +0000615 if (CL->isFileScope())
616 sReg = getGlobalsRegion();
617 else {
618 const StackFrameContext *STC = LC->getCurrentStackFrame();
619 assert(STC);
620 sReg = getStackLocalsRegion(STC);
621 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000622
Ted Kremenek67d12872009-12-07 22:05:27 +0000623 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000624}
625
Ted Kremenekb48ad642009-12-04 00:26:31 +0000626const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000627MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000628 const MemRegion* superRegion,
629 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000630
Ted Kremenek32f90102010-05-27 00:29:00 +0000631 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
Ted Kremenekabb042f2008-12-13 19:24:37 +0000632
Zhongxing Xu511191c2008-10-21 05:27:10 +0000633 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000634 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000635
636 void* InsertPos;
637 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
638 ElementRegion* R = cast_or_null<ElementRegion>(data);
639
640 if (!R) {
641 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000642 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000643 Regions.InsertNode(R, InsertPos);
644 }
645
646 return R;
647}
648
Ted Kremenekb48ad642009-12-04 00:26:31 +0000649const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000650MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000651 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000652}
653
Ted Kremenekb48ad642009-12-04 00:26:31 +0000654const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000655MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
656 AnalysisContext *AC) {
657 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000658}
659
660
Ted Kremenek993f1c72008-10-17 20:28:54 +0000661/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000662const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000663 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000664}
665
Ted Kremenekde0d2632010-01-05 02:18:06 +0000666const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000667MemRegionManager::getFieldRegion(const FieldDecl* d,
668 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000669 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000670}
671
Ted Kremenekb48ad642009-12-04 00:26:31 +0000672const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000673MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
674 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000675 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000676}
677
Ted Kremenekde0d2632010-01-05 02:18:06 +0000678const CXXObjectRegion*
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000679MemRegionManager::getCXXObjectRegion(Expr const *E,
680 LocationContext const *LC) {
681 const StackFrameContext *SFC = LC->getCurrentStackFrame();
682 assert(SFC);
683 return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000684}
685
Ted Kremenekde0d2632010-01-05 02:18:06 +0000686const CXXThisRegion*
687MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
688 const LocationContext *LC) {
689 const StackFrameContext *STC = LC->getCurrentStackFrame();
690 assert(STC);
691 const PointerType *PT = thisPointerTy->getAs<PointerType>();
692 assert(PT);
693 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
694}
695
Ted Kremenekb48ad642009-12-04 00:26:31 +0000696const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000697MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
698 const LocationContext *LC) {
699 const StackFrameContext *STC = LC->getCurrentStackFrame();
700 assert(STC);
701 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000702}
703
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000704const MemSpaceRegion *MemRegion::getMemorySpace() const {
705 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000706 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000707
Ted Kremenek993f1c72008-10-17 20:28:54 +0000708 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000709 R = SR->getSuperRegion();
710 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000711 }
Mike Stump1eb44332009-09-09 15:08:12 +0000712
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000713 return dyn_cast<MemSpaceRegion>(R);
714}
715
716bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000717 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000718}
Ted Kremenek1670e402009-04-11 00:11:10 +0000719
Ted Kremenekde0d2632010-01-05 02:18:06 +0000720bool MemRegion::hasStackNonParametersStorage() const {
721 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000722}
Ted Kremenek1670e402009-04-11 00:11:10 +0000723
Ted Kremenekde0d2632010-01-05 02:18:06 +0000724bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000725 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000726}
727
Ted Kremenek15086362009-07-02 18:25:09 +0000728bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000729 const MemSpaceRegion *MS = getMemorySpace();
730 return isa<StackArgumentsSpaceRegion>(MS) ||
731 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000732}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000733
Zhongxing Xuadca2712009-11-10 02:37:53 +0000734// getBaseRegion strips away all elements and fields, and get the base region
735// of them.
736const MemRegion *MemRegion::getBaseRegion() const {
737 const MemRegion *R = this;
738 while (true) {
Ted Kremenek68b9a592010-04-06 22:06:03 +0000739 switch (R->getKind()) {
740 case MemRegion::ElementRegionKind:
741 case MemRegion::FieldRegionKind:
742 case MemRegion::ObjCIvarRegionKind:
743 R = cast<SubRegion>(R)->getSuperRegion();
744 continue;
745 default:
746 break;
Zhongxing Xuadca2712009-11-10 02:37:53 +0000747 }
748 break;
749 }
750 return R;
751}
752
Ted Kremenek1670e402009-04-11 00:11:10 +0000753//===----------------------------------------------------------------------===//
754// View handling.
755//===----------------------------------------------------------------------===//
756
Zhongxing Xu479529e2009-11-10 02:17:20 +0000757const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000758 const MemRegion *R = this;
759 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000760 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000761 // FIXME: generalize. Essentially we want to strip away ElementRegions
762 // that were layered on a symbolic region because of casts. We only
763 // want to strip away ElementRegions, however, where the index is 0.
764 SVal index = ER->getIndex();
765 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000766 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000767 R = ER->getSuperRegion();
768 continue;
769 }
770 }
771 }
772 break;
773 }
774 return R;
775}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000776
777// FIXME: Merge with the implementation of the same method in Store.cpp
778static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
779 if (const RecordType *RT = Ty->getAs<RecordType>()) {
780 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000781 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000782 return false;
783 }
784
785 return true;
786}
787
788RegionRawOffset ElementRegion::getAsRawOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000789 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000790 const ElementRegion *ER = this;
791 const MemRegion *superR = NULL;
792 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000793
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000794 // FIXME: Handle multi-dimensional arrays.
795
796 while (ER) {
797 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000798
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000799 // FIXME: generalize to symbolic offsets.
800 SVal index = ER->getIndex();
801 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
802 // Update the offset.
803 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000804
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000805 if (i != 0) {
806 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000807
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000808 // If we are pointing to an incomplete type, go no further.
809 if (!IsCompleteType(C, elemType)) {
810 superR = ER;
811 break;
812 }
Mike Stump1eb44332009-09-09 15:08:12 +0000813
Ken Dyck199c3d62010-01-11 17:06:35 +0000814 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000815 offset += (i * size);
816 }
817
818 // Go to the next ElementRegion (if any).
819 ER = dyn_cast<ElementRegion>(superR);
820 continue;
821 }
Mike Stump1eb44332009-09-09 15:08:12 +0000822
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000823 return NULL;
824 }
Mike Stump1eb44332009-09-09 15:08:12 +0000825
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000826 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000827 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000828}
829
Ted Kremenek42400962009-11-26 02:34:36 +0000830//===----------------------------------------------------------------------===//
831// BlockDataRegion
832//===----------------------------------------------------------------------===//
833
834void BlockDataRegion::LazyInitializeReferencedVars() {
835 if (ReferencedVars)
836 return;
837
Ted Kremenek67d12872009-12-07 22:05:27 +0000838 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000839 AnalysisContext::referenced_decls_iterator I, E;
840 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000841
Ted Kremenek42400962009-11-26 02:34:36 +0000842 if (I == E) {
843 ReferencedVars = (void*) 0x1;
844 return;
845 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000846
Ted Kremenek42400962009-11-26 02:34:36 +0000847 MemRegionManager &MemMgr = *getMemRegionManager();
848 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
849 BumpVectorContext BC(A);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000850
Ted Kremenek42400962009-11-26 02:34:36 +0000851 typedef BumpVector<const MemRegion*> VarVec;
852 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000853 new (BV) VarVec(BC, E - I);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000854
Ted Kremenek67d12872009-12-07 22:05:27 +0000855 for ( ; I != E; ++I) {
856 const VarDecl *VD = *I;
857 const VarRegion *VR = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000858
Ted Kremenek85248732010-02-06 00:30:00 +0000859 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000860 VR = MemMgr.getVarRegion(VD, this);
861 else {
862 if (LC)
863 VR = MemMgr.getVarRegion(VD, LC);
864 else {
865 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
866 }
867 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000868
Ted Kremenek67d12872009-12-07 22:05:27 +0000869 assert(VR);
870 BV->push_back(VR, BC);
871 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000872
Ted Kremenek42400962009-11-26 02:34:36 +0000873 ReferencedVars = BV;
874}
875
876BlockDataRegion::referenced_vars_iterator
877BlockDataRegion::referenced_vars_begin() const {
878 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
879
880 BumpVector<const MemRegion*> *Vec =
881 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000882
Ted Kremenek81cef582009-12-03 08:09:21 +0000883 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
884 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000885}
886
887BlockDataRegion::referenced_vars_iterator
888BlockDataRegion::referenced_vars_end() const {
889 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
890
891 BumpVector<const MemRegion*> *Vec =
892 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000893
Ted Kremenek81cef582009-12-03 08:09:21 +0000894 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
895 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000896}