blob: 575458c9dc798762c9d9d1f57a093be71b750e7b [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"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000017#include "clang/Analysis/AnalysisContext.h"
18#include "clang/Analysis/Support/BumpVector.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000019#include "clang/AST/CharUnits.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000020#include "llvm/Support/raw_ostream.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000021
22using namespace clang;
23
Ted Kremenek25010132009-06-22 23:13:13 +000024//===----------------------------------------------------------------------===//
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000025// MemRegion Construction.
26//===----------------------------------------------------------------------===//
27
28template<typename RegionTy> struct MemRegionManagerTrait;
29
30template <typename RegionTy, typename A1>
31RegionTy* MemRegionManager::getRegion(const A1 a1) {
32
33 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
34 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
35
36 llvm::FoldingSetNodeID ID;
37 RegionTy::ProfileRegion(ID, a1, superRegion);
38 void* InsertPos;
39 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
40 InsertPos));
41
42 if (!R) {
43 R = (RegionTy*) A.Allocate<RegionTy>();
44 new (R) RegionTy(a1, superRegion);
45 Regions.InsertNode(R, InsertPos);
46 }
47
48 return R;
49}
50
51template <typename RegionTy, typename A1>
52RegionTy* MemRegionManager::getSubRegion(const A1 a1,
53 const MemRegion *superRegion) {
54 llvm::FoldingSetNodeID ID;
55 RegionTy::ProfileRegion(ID, a1, superRegion);
56 void* InsertPos;
57 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
58 InsertPos));
59
60 if (!R) {
61 R = (RegionTy*) A.Allocate<RegionTy>();
62 new (R) RegionTy(a1, superRegion);
63 Regions.InsertNode(R, InsertPos);
64 }
65
66 return R;
67}
68
69template <typename RegionTy, typename A1, typename A2>
70RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
71
72 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
73 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
74
75 llvm::FoldingSetNodeID ID;
76 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
77 void* InsertPos;
78 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
79 InsertPos));
80
81 if (!R) {
82 R = (RegionTy*) A.Allocate<RegionTy>();
83 new (R) RegionTy(a1, a2, superRegion);
84 Regions.InsertNode(R, InsertPos);
85 }
86
87 return R;
88}
89
90template <typename RegionTy, typename A1, typename A2>
91RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
92 const MemRegion *superRegion) {
93
94 llvm::FoldingSetNodeID ID;
95 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
96 void* InsertPos;
97 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
98 InsertPos));
99
100 if (!R) {
101 R = (RegionTy*) A.Allocate<RegionTy>();
102 new (R) RegionTy(a1, a2, superRegion);
103 Regions.InsertNode(R, InsertPos);
104 }
105
106 return R;
107}
108
Ted Kremenek67d12872009-12-07 22:05:27 +0000109template <typename RegionTy, typename A1, typename A2, typename A3>
110RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
111 const MemRegion *superRegion) {
112
113 llvm::FoldingSetNodeID ID;
114 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
115 void* InsertPos;
116 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
117 InsertPos));
118
119 if (!R) {
120 R = (RegionTy*) A.Allocate<RegionTy>();
121 new (R) RegionTy(a1, a2, a3, superRegion);
122 Regions.InsertNode(R, InsertPos);
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000123 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000124
125 return R;
126}
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000127
128//===----------------------------------------------------------------------===//
Ted Kremenek42400962009-11-26 02:34:36 +0000129// Object destruction.
Ted Kremenek25010132009-06-22 23:13:13 +0000130//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000131
132MemRegion::~MemRegion() {}
133
Ted Kremenek42400962009-11-26 02:34:36 +0000134MemRegionManager::~MemRegionManager() {
135 // All regions and their data are BumpPtrAllocated. No need to call
136 // their destructors.
137}
138
139//===----------------------------------------------------------------------===//
140// Basic methods.
141//===----------------------------------------------------------------------===//
142
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +0000143bool SubRegion::isSubRegionOf(const MemRegion* R) const {
144 const MemRegion* r = getSuperRegion();
145 while (r != 0) {
146 if (r == R)
147 return true;
148 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
149 r = sr->getSuperRegion();
150 else
151 break;
152 }
153 return false;
154}
155
Ted Kremeneka43484a2009-06-23 00:46:41 +0000156MemRegionManager* SubRegion::getMemRegionManager() const {
157 const SubRegion* r = this;
158 do {
159 const MemRegion *superRegion = r->getSuperRegion();
160 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
161 r = sr;
162 continue;
163 }
164 return superRegion->getMemRegionManager();
165 } while (1);
166}
167
Ted Kremenek5348f942009-12-14 22:15:06 +0000168const StackFrameContext *VarRegion::getStackFrame() const {
169 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
170 return SSR ? SSR->getStackFrame() : NULL;
171}
172
173//===----------------------------------------------------------------------===//
174// FoldingSet profiling.
175//===----------------------------------------------------------------------===//
176
Ted Kremenek9e240492008-10-04 05:50:14 +0000177void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
178 ID.AddInteger((unsigned)getKind());
179}
180
Ted Kremenek67d12872009-12-07 22:05:27 +0000181void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
182 ID.AddInteger((unsigned)getKind());
183 ID.AddPointer(getStackFrame());
184}
185
Mike Stump1eb44332009-09-09 15:08:12 +0000186void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
187 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000188 const MemRegion* superRegion) {
189 ID.AddInteger((unsigned) StringRegionKind);
190 ID.AddPointer(Str);
191 ID.AddPointer(superRegion);
192}
193
Ted Kremenek7090ae12008-11-02 00:34:33 +0000194void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000195 const Expr* Ex, unsigned cnt,
196 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000197 ID.AddInteger((unsigned) AllocaRegionKind);
198 ID.AddPointer(Ex);
199 ID.AddInteger(cnt);
200}
201
202void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000203 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000204}
205
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000206void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
207 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
208}
209
210void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
211 const CompoundLiteralExpr* CL,
212 const MemRegion* superRegion) {
213 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
214 ID.AddPointer(CL);
215 ID.AddPointer(superRegion);
216}
217
Ted Kremenekde0d2632010-01-05 02:18:06 +0000218void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
219 const PointerType *PT,
220 const MemRegion *sRegion) {
221 ID.AddInteger((unsigned) CXXThisRegionKind);
222 ID.AddPointer(PT);
223 ID.AddPointer(sRegion);
224}
225
226void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
227 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
228}
229
Ted Kremenek9e240492008-10-04 05:50:14 +0000230void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
231 const MemRegion* superRegion, Kind k) {
232 ID.AddInteger((unsigned) k);
233 ID.AddPointer(D);
234 ID.AddPointer(superRegion);
235}
236
237void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
238 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
239}
240
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000241void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000242 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000243}
244
Ted Kremenek25010132009-06-22 23:13:13 +0000245void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
246 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000247 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000248 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000249 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000250}
251
252void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000253 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000254}
255
Ted Kremenekf936f452009-05-04 06:18:28 +0000256void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000257 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000258 const MemRegion* superRegion) {
259 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000260 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000261 ID.AddPointer(superRegion);
262 Idx.Profile(ID);
263}
264
265void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000266 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000267}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000268
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000269void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
270 const FunctionDecl *FD,
271 const MemRegion*) {
272 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000273 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000274}
275
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000276void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
277 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
278}
279
280void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000281 const BlockDecl *BD, CanQualType,
282 const AnalysisContext *AC,
283 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000284 ID.AddInteger(MemRegion::BlockTextRegionKind);
285 ID.AddPointer(BD);
286}
287
288void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000289 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000290}
291
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000292void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
293 const BlockTextRegion *BC,
294 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000295 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000296 ID.AddInteger(MemRegion::BlockDataRegionKind);
297 ID.AddPointer(BC);
298 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000299 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000300}
301
302void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000303 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000304}
305
Zhongxing Xubb141212009-12-16 11:27:52 +0000306void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000307 Expr const *Ex,
Zhongxing Xubb141212009-12-16 11:27:52 +0000308 const MemRegion *sReg) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000309 ID.AddPointer(Ex);
Zhongxing Xubb141212009-12-16 11:27:52 +0000310 ID.AddPointer(sReg);
311}
312
313void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000314 ProfileRegion(ID, Ex, getSuperRegion());
Zhongxing Xubb141212009-12-16 11:27:52 +0000315}
316
Zhongxing Xu026c6632009-02-05 06:57:29 +0000317//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000318// Region pretty-printing.
319//===----------------------------------------------------------------------===//
320
Ted Kremenek8800ad42009-07-13 23:31:04 +0000321void MemRegion::dump() const {
322 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000323}
324
Ted Kremenek9e240492008-10-04 05:50:14 +0000325std::string MemRegion::getString() const {
326 std::string s;
327 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000328 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000329 return os.str();
330}
331
Ted Kremenek8800ad42009-07-13 23:31:04 +0000332void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000333 os << "<Unknown Region>";
334}
335
Ted Kremenek8800ad42009-07-13 23:31:04 +0000336void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000337 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
338}
339
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000340void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000341 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000342}
343
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000344void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000345 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000346}
347
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000348void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
349 os << "block_data{" << BC << '}';
350}
351
352
Ted Kremenek8800ad42009-07-13 23:31:04 +0000353void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000354 // FIXME: More elaborate pretty-printing.
355 os << "{ " << (void*) CL << " }";
356}
357
Ted Kremenekde0d2632010-01-05 02:18:06 +0000358void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
359 os << "this";
360}
361
Ted Kremenek8800ad42009-07-13 23:31:04 +0000362void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000363 os << "element{" << superRegion << ','
364 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000365}
366
Ted Kremenek8800ad42009-07-13 23:31:04 +0000367void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000368 os << superRegion << "->" << getDecl();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000369}
370
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000371void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000372 os << "ivar{" << superRegion << ',' << getDecl() << '}';
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000373}
374
Mike Stump1eb44332009-09-09 15:08:12 +0000375void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000376 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000377}
378
Ted Kremenek8800ad42009-07-13 23:31:04 +0000379void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000380 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000381}
382
Ted Kremenek8800ad42009-07-13 23:31:04 +0000383void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000384 os << cast<VarDecl>(D);
Ted Kremenek9e240492008-10-04 05:50:14 +0000385}
386
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000387void RegionRawOffset::dump() const {
388 dumpToStream(llvm::errs());
389}
390
391void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
392 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
393}
394
Ted Kremenek9e240492008-10-04 05:50:14 +0000395//===----------------------------------------------------------------------===//
396// MemRegionManager methods.
397//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000398
Ted Kremenek67d12872009-12-07 22:05:27 +0000399template <typename REG>
400const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000401 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000402 region = (REG*) A.Allocate<REG>();
403 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000404 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000405
Ted Kremenek9e240492008-10-04 05:50:14 +0000406 return region;
407}
408
Ted Kremenek67d12872009-12-07 22:05:27 +0000409template <typename REG, typename ARG>
410const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
411 if (!region) {
412 region = (REG*) A.Allocate<REG>();
413 new (region) REG(this, a);
414 }
415
416 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000417}
418
Ted Kremenek67d12872009-12-07 22:05:27 +0000419const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000420MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
421 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000422 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
423
424 if (R)
425 return R;
426
427 R = A.Allocate<StackLocalsSpaceRegion>();
428 new (R) StackLocalsSpaceRegion(this, STC);
429 return R;
Ted Kremenekd05552a2009-07-02 18:14:59 +0000430}
431
Ted Kremenek67d12872009-12-07 22:05:27 +0000432const StackArgumentsSpaceRegion *
433MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000434 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000435 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
436
437 if (R)
438 return R;
439
440 R = A.Allocate<StackArgumentsSpaceRegion>();
441 new (R) StackArgumentsSpaceRegion(this, STC);
442 return R;
Ted Kremenek67d12872009-12-07 22:05:27 +0000443}
444
445const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000446 return LazyAllocate(globals);
447}
448
Ted Kremenek67d12872009-12-07 22:05:27 +0000449const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000450 return LazyAllocate(heap);
451}
452
Ted Kremenekb48ad642009-12-04 00:26:31 +0000453const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000454 return LazyAllocate(unknown);
455}
456
Ted Kremenekb48ad642009-12-04 00:26:31 +0000457const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000458 return LazyAllocate(code);
459}
460
Ted Kremenek25010132009-06-22 23:13:13 +0000461//===----------------------------------------------------------------------===//
462// Constructing regions.
463//===----------------------------------------------------------------------===//
464
Ted Kremenekb48ad642009-12-04 00:26:31 +0000465const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000466 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000467}
468
Ted Kremenekb48ad642009-12-04 00:26:31 +0000469const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
470 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000471 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000472
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000473 if (D->hasLocalStorage()) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000474 // FIXME: Once we implement scope handling, we will need to properly lookup
475 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000476 const DeclContext *DC = D->getDeclContext();
477 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000478
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000479 if (!STC)
480 sReg = getUnknownRegion();
481 else {
482 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
483 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
484 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
485 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000486 }
487 else {
488 sReg = getGlobalsRegion();
489 }
490
491 return getSubRegion<VarRegion>(D, sReg);
492}
493
494const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
495 const MemRegion *superR) {
496 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000497}
498
Ted Kremenekb48ad642009-12-04 00:26:31 +0000499const BlockDataRegion *
500MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
501 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000502 const MemRegion *sReg = 0;
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000503
Ted Kremenek67d12872009-12-07 22:05:27 +0000504 if (LC) {
505 // FIXME: Once we implement scope handling, we want the parent region
506 // to be the scope.
507 const StackFrameContext *STC = LC->getCurrentStackFrame();
508 assert(STC);
509 sReg = getStackLocalsRegion(STC);
510 }
511 else {
512 // We allow 'LC' to be NULL for cases where want BlockDataRegions
513 // without context-sensitivity.
514 sReg = getUnknownRegion();
515 }
516
517 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000518}
519
Ted Kremenekb48ad642009-12-04 00:26:31 +0000520const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000521MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
522 const LocationContext *LC) {
523
524 const MemRegion *sReg = 0;
525
526 if (CL->isFileScope())
527 sReg = getGlobalsRegion();
528 else {
529 const StackFrameContext *STC = LC->getCurrentStackFrame();
530 assert(STC);
531 sReg = getStackLocalsRegion(STC);
532 }
533
534 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000535}
536
Ted Kremenekb48ad642009-12-04 00:26:31 +0000537const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000538MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000539 const MemRegion* superRegion,
540 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000541
Ted Kremenek32f90102010-05-27 00:29:00 +0000542 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
Ted Kremenekabb042f2008-12-13 19:24:37 +0000543
Zhongxing Xu511191c2008-10-21 05:27:10 +0000544 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000545 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000546
547 void* InsertPos;
548 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
549 ElementRegion* R = cast_or_null<ElementRegion>(data);
550
551 if (!R) {
552 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000553 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000554 Regions.InsertNode(R, InsertPos);
555 }
556
557 return R;
558}
559
Ted Kremenekb48ad642009-12-04 00:26:31 +0000560const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000561MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000562 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000563}
564
Ted Kremenekb48ad642009-12-04 00:26:31 +0000565const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000566MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
567 AnalysisContext *AC) {
568 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000569}
570
571
Ted Kremenek993f1c72008-10-17 20:28:54 +0000572/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000573const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000574 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000575}
576
Ted Kremenekde0d2632010-01-05 02:18:06 +0000577const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000578MemRegionManager::getFieldRegion(const FieldDecl* d,
579 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000580 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000581}
582
Ted Kremenekb48ad642009-12-04 00:26:31 +0000583const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000584MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
585 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000586 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000587}
588
Ted Kremenekde0d2632010-01-05 02:18:06 +0000589const CXXObjectRegion*
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000590MemRegionManager::getCXXObjectRegion(Expr const *E,
591 LocationContext const *LC) {
592 const StackFrameContext *SFC = LC->getCurrentStackFrame();
593 assert(SFC);
594 return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000595}
596
Ted Kremenekde0d2632010-01-05 02:18:06 +0000597const CXXThisRegion*
598MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
599 const LocationContext *LC) {
600 const StackFrameContext *STC = LC->getCurrentStackFrame();
601 assert(STC);
602 const PointerType *PT = thisPointerTy->getAs<PointerType>();
603 assert(PT);
604 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
605}
606
Ted Kremenekb48ad642009-12-04 00:26:31 +0000607const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000608MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
609 const LocationContext *LC) {
610 const StackFrameContext *STC = LC->getCurrentStackFrame();
611 assert(STC);
612 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000613}
614
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000615const MemSpaceRegion *MemRegion::getMemorySpace() const {
616 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000617 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000618
Ted Kremenek993f1c72008-10-17 20:28:54 +0000619 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000620 R = SR->getSuperRegion();
621 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000622 }
Mike Stump1eb44332009-09-09 15:08:12 +0000623
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000624 return dyn_cast<MemSpaceRegion>(R);
625}
626
627bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000628 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000629}
Ted Kremenek1670e402009-04-11 00:11:10 +0000630
Ted Kremenekde0d2632010-01-05 02:18:06 +0000631bool MemRegion::hasStackNonParametersStorage() const {
632 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000633}
Ted Kremenek1670e402009-04-11 00:11:10 +0000634
Ted Kremenekde0d2632010-01-05 02:18:06 +0000635bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000636 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000637}
638
Ted Kremenek15086362009-07-02 18:25:09 +0000639bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000640 const MemSpaceRegion *MS = getMemorySpace();
641 return isa<StackArgumentsSpaceRegion>(MS) ||
642 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000643}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000644
Zhongxing Xuadca2712009-11-10 02:37:53 +0000645// getBaseRegion strips away all elements and fields, and get the base region
646// of them.
647const MemRegion *MemRegion::getBaseRegion() const {
648 const MemRegion *R = this;
649 while (true) {
Ted Kremenek68b9a592010-04-06 22:06:03 +0000650 switch (R->getKind()) {
651 case MemRegion::ElementRegionKind:
652 case MemRegion::FieldRegionKind:
653 case MemRegion::ObjCIvarRegionKind:
654 R = cast<SubRegion>(R)->getSuperRegion();
655 continue;
656 default:
657 break;
Zhongxing Xuadca2712009-11-10 02:37:53 +0000658 }
659 break;
660 }
661 return R;
662}
663
Ted Kremenek1670e402009-04-11 00:11:10 +0000664//===----------------------------------------------------------------------===//
665// View handling.
666//===----------------------------------------------------------------------===//
667
Zhongxing Xu479529e2009-11-10 02:17:20 +0000668const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000669 const MemRegion *R = this;
670 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000671 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000672 // FIXME: generalize. Essentially we want to strip away ElementRegions
673 // that were layered on a symbolic region because of casts. We only
674 // want to strip away ElementRegions, however, where the index is 0.
675 SVal index = ER->getIndex();
676 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000677 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000678 R = ER->getSuperRegion();
679 continue;
680 }
681 }
682 }
683 break;
684 }
685 return R;
686}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000687
688// FIXME: Merge with the implementation of the same method in Store.cpp
689static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
690 if (const RecordType *RT = Ty->getAs<RecordType>()) {
691 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000692 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000693 return false;
694 }
695
696 return true;
697}
698
699RegionRawOffset ElementRegion::getAsRawOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000700 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000701 const ElementRegion *ER = this;
702 const MemRegion *superR = NULL;
703 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000704
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000705 // FIXME: Handle multi-dimensional arrays.
706
707 while (ER) {
708 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000709
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000710 // FIXME: generalize to symbolic offsets.
711 SVal index = ER->getIndex();
712 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
713 // Update the offset.
714 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000715
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000716 if (i != 0) {
717 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000718
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000719 // If we are pointing to an incomplete type, go no further.
720 if (!IsCompleteType(C, elemType)) {
721 superR = ER;
722 break;
723 }
Mike Stump1eb44332009-09-09 15:08:12 +0000724
Ken Dyck199c3d62010-01-11 17:06:35 +0000725 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000726 offset += (i * size);
727 }
728
729 // Go to the next ElementRegion (if any).
730 ER = dyn_cast<ElementRegion>(superR);
731 continue;
732 }
Mike Stump1eb44332009-09-09 15:08:12 +0000733
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000734 return NULL;
735 }
Mike Stump1eb44332009-09-09 15:08:12 +0000736
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000737 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000738 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000739}
740
Ted Kremenek42400962009-11-26 02:34:36 +0000741//===----------------------------------------------------------------------===//
742// BlockDataRegion
743//===----------------------------------------------------------------------===//
744
745void BlockDataRegion::LazyInitializeReferencedVars() {
746 if (ReferencedVars)
747 return;
748
Ted Kremenek67d12872009-12-07 22:05:27 +0000749 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000750 AnalysisContext::referenced_decls_iterator I, E;
751 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
752
753 if (I == E) {
754 ReferencedVars = (void*) 0x1;
755 return;
756 }
757
758 MemRegionManager &MemMgr = *getMemRegionManager();
759 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
760 BumpVectorContext BC(A);
761
762 typedef BumpVector<const MemRegion*> VarVec;
763 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000764 new (BV) VarVec(BC, E - I);
Ted Kremenek42400962009-11-26 02:34:36 +0000765
Ted Kremenek67d12872009-12-07 22:05:27 +0000766 for ( ; I != E; ++I) {
767 const VarDecl *VD = *I;
768 const VarRegion *VR = 0;
769
Ted Kremenek85248732010-02-06 00:30:00 +0000770 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000771 VR = MemMgr.getVarRegion(VD, this);
772 else {
773 if (LC)
774 VR = MemMgr.getVarRegion(VD, LC);
775 else {
776 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
777 }
778 }
779
780 assert(VR);
781 BV->push_back(VR, BC);
782 }
Ted Kremenek42400962009-11-26 02:34:36 +0000783
784 ReferencedVars = BV;
785}
786
787BlockDataRegion::referenced_vars_iterator
788BlockDataRegion::referenced_vars_begin() const {
789 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
790
791 BumpVector<const MemRegion*> *Vec =
792 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
793
Ted Kremenek81cef582009-12-03 08:09:21 +0000794 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
795 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000796}
797
798BlockDataRegion::referenced_vars_iterator
799BlockDataRegion::referenced_vars_end() const {
800 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
801
802 BumpVector<const MemRegion*> *Vec =
803 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
804
Ted Kremenek81cef582009-12-03 08:09:21 +0000805 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
806 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000807}