blob: 04d730c5c80fb9a2339b605ec22558f83067899a [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
16#include "llvm/Support/raw_ostream.h"
17#include "clang/Analysis/PathSensitive/MemRegion.h"
Ted Kremenek19e1f0b2009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenek82cd37c2009-08-21 23:25:54 +000019#include "clang/Analysis/PathSensitive/AnalysisContext.h"
Ted Kremenek42400962009-11-26 02:34:36 +000020#include "clang/AST/StmtVisitor.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 Kremenek9e240492008-10-04 05:50:14 +0000218void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
219 const MemRegion* superRegion, Kind k) {
220 ID.AddInteger((unsigned) k);
221 ID.AddPointer(D);
222 ID.AddPointer(superRegion);
223}
224
225void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
226 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
227}
228
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000229void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000230 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000231}
232
Ted Kremenek25010132009-06-22 23:13:13 +0000233void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
234 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000235 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000236 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000237 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000238}
239
240void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000241 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000242}
243
Ted Kremenekf936f452009-05-04 06:18:28 +0000244void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000245 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000246 const MemRegion* superRegion) {
247 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000248 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000249 ID.AddPointer(superRegion);
250 Idx.Profile(ID);
251}
252
253void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000254 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000255}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000256
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000257void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
258 const FunctionDecl *FD,
259 const MemRegion*) {
260 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000261 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000262}
263
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000264void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
265 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
266}
267
268void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000269 const BlockDecl *BD, CanQualType,
270 const AnalysisContext *AC,
271 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000272 ID.AddInteger(MemRegion::BlockTextRegionKind);
273 ID.AddPointer(BD);
274}
275
276void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000277 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000278}
279
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000280void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
281 const BlockTextRegion *BC,
282 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000283 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000284 ID.AddInteger(MemRegion::BlockDataRegionKind);
285 ID.AddPointer(BC);
286 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000287 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000288}
289
290void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000291 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000292}
293
Zhongxing Xubb141212009-12-16 11:27:52 +0000294void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
295 QualType T,
296 const MemRegion *sReg) {
297 ID.AddPointer(T.getTypePtr());
298 ID.AddPointer(sReg);
299}
300
301void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
302 ProfileRegion(ID, T, getSuperRegion());
303}
304
Zhongxing Xu026c6632009-02-05 06:57:29 +0000305//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000306// Region pretty-printing.
307//===----------------------------------------------------------------------===//
308
Ted Kremenek8800ad42009-07-13 23:31:04 +0000309void MemRegion::dump() const {
310 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000311}
312
Ted Kremenek9e240492008-10-04 05:50:14 +0000313std::string MemRegion::getString() const {
314 std::string s;
315 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000316 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000317 return os.str();
318}
319
Ted Kremenek8800ad42009-07-13 23:31:04 +0000320void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000321 os << "<Unknown Region>";
322}
323
Ted Kremenek8800ad42009-07-13 23:31:04 +0000324void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000325 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
326}
327
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000328void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000329 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000330}
331
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000332void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000333 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000334}
335
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000336void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
337 os << "block_data{" << BC << '}';
338}
339
340
Ted Kremenek8800ad42009-07-13 23:31:04 +0000341void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000342 // FIXME: More elaborate pretty-printing.
343 os << "{ " << (void*) CL << " }";
344}
345
Ted Kremenek8800ad42009-07-13 23:31:04 +0000346void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000347 os << "element{" << superRegion << ','
348 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000349}
350
Ted Kremenek8800ad42009-07-13 23:31:04 +0000351void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
352 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000353}
354
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000355void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
356 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
357}
358
Mike Stump1eb44332009-09-09 15:08:12 +0000359void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000360 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000361}
362
Ted Kremenek8800ad42009-07-13 23:31:04 +0000363void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000364 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000365}
366
Ted Kremenek8800ad42009-07-13 23:31:04 +0000367void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000368 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000369}
370
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000371void RegionRawOffset::dump() const {
372 dumpToStream(llvm::errs());
373}
374
375void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
376 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
377}
378
Ted Kremenek9e240492008-10-04 05:50:14 +0000379//===----------------------------------------------------------------------===//
380// MemRegionManager methods.
381//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000382
Ted Kremenek67d12872009-12-07 22:05:27 +0000383template <typename REG>
384const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000385 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000386 region = (REG*) A.Allocate<REG>();
387 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000388 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000389
Ted Kremenek9e240492008-10-04 05:50:14 +0000390 return region;
391}
392
Ted Kremenek67d12872009-12-07 22:05:27 +0000393template <typename REG, typename ARG>
394const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
395 if (!region) {
396 region = (REG*) A.Allocate<REG>();
397 new (region) REG(this, a);
398 }
399
400 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000401}
402
Ted Kremenek67d12872009-12-07 22:05:27 +0000403const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000404MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
405 assert(STC);
406 if (STC == cachedStackLocalsFrame)
407 return cachedStackLocalsRegion;
408 cachedStackLocalsFrame = STC;
409 return LazyAllocate(cachedStackLocalsRegion, STC);
Ted Kremenekd05552a2009-07-02 18:14:59 +0000410}
411
Ted Kremenek67d12872009-12-07 22:05:27 +0000412const StackArgumentsSpaceRegion *
413MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000414 assert(STC);
415 if (STC == cachedStackArgumentsFrame)
416 return cachedStackArgumentsRegion;
417
418 cachedStackArgumentsFrame = STC;
419 return LazyAllocate(cachedStackArgumentsRegion, STC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000420}
421
422const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000423 return LazyAllocate(globals);
424}
425
Ted Kremenek67d12872009-12-07 22:05:27 +0000426const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000427 return LazyAllocate(heap);
428}
429
Ted Kremenekb48ad642009-12-04 00:26:31 +0000430const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000431 return LazyAllocate(unknown);
432}
433
Ted Kremenekb48ad642009-12-04 00:26:31 +0000434const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000435 return LazyAllocate(code);
436}
437
Ted Kremenek25010132009-06-22 23:13:13 +0000438//===----------------------------------------------------------------------===//
439// Constructing regions.
440//===----------------------------------------------------------------------===//
441
Ted Kremenekb48ad642009-12-04 00:26:31 +0000442const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000443 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000444}
445
Ted Kremenekb48ad642009-12-04 00:26:31 +0000446const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
447 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000448 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000449
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000450 if (D->hasLocalStorage()) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000451 // FIXME: Once we implement scope handling, we will need to properly lookup
452 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000453 const DeclContext *DC = D->getDeclContext();
454 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000455
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000456 if (!STC)
457 sReg = getUnknownRegion();
458 else {
459 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
460 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
461 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
462 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000463 }
464 else {
465 sReg = getGlobalsRegion();
466 }
467
468 return getSubRegion<VarRegion>(D, sReg);
469}
470
471const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
472 const MemRegion *superR) {
473 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000474}
475
Ted Kremenekb48ad642009-12-04 00:26:31 +0000476const BlockDataRegion *
477MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
478 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000479 const MemRegion *sReg = 0;
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000480
Ted Kremenek67d12872009-12-07 22:05:27 +0000481 if (LC) {
482 // FIXME: Once we implement scope handling, we want the parent region
483 // to be the scope.
484 const StackFrameContext *STC = LC->getCurrentStackFrame();
485 assert(STC);
486 sReg = getStackLocalsRegion(STC);
487 }
488 else {
489 // We allow 'LC' to be NULL for cases where want BlockDataRegions
490 // without context-sensitivity.
491 sReg = getUnknownRegion();
492 }
493
494 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000495}
496
Ted Kremenekb48ad642009-12-04 00:26:31 +0000497const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000498MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
499 const LocationContext *LC) {
500
501 const MemRegion *sReg = 0;
502
503 if (CL->isFileScope())
504 sReg = getGlobalsRegion();
505 else {
506 const StackFrameContext *STC = LC->getCurrentStackFrame();
507 assert(STC);
508 sReg = getStackLocalsRegion(STC);
509 }
510
511 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000512}
513
Ted Kremenekb48ad642009-12-04 00:26:31 +0000514const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000515MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000516 const MemRegion* superRegion,
517 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000518
519 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000520
Zhongxing Xu511191c2008-10-21 05:27:10 +0000521 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000522 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000523
524 void* InsertPos;
525 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
526 ElementRegion* R = cast_or_null<ElementRegion>(data);
527
528 if (!R) {
529 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000530 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000531 Regions.InsertNode(R, InsertPos);
532 }
533
534 return R;
535}
536
Ted Kremenekb48ad642009-12-04 00:26:31 +0000537const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000538MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000539 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000540}
541
Ted Kremenekb48ad642009-12-04 00:26:31 +0000542const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000543MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
544 AnalysisContext *AC) {
545 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000546}
547
548
Ted Kremenek993f1c72008-10-17 20:28:54 +0000549/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000550const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000551 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000552}
553
Ted Kremenekb48ad642009-12-04 00:26:31 +0000554const FieldRegion *
555MemRegionManager::getFieldRegion(const FieldDecl* d,
556 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000557 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000558}
559
Ted Kremenekb48ad642009-12-04 00:26:31 +0000560const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000561MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
562 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000563 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000564}
565
Ted Kremenekb48ad642009-12-04 00:26:31 +0000566const ObjCObjectRegion*
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000567MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000568 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000569 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000570}
571
Zhongxing Xubb141212009-12-16 11:27:52 +0000572const CXXObjectRegion *
573MemRegionManager::getCXXObjectRegion(QualType T) {
574 return getSubRegion<CXXObjectRegion>(T, getUnknownRegion());
575}
576
Ted Kremenekb48ad642009-12-04 00:26:31 +0000577const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000578MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
579 const LocationContext *LC) {
580 const StackFrameContext *STC = LC->getCurrentStackFrame();
581 assert(STC);
582 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000583}
584
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000585const MemSpaceRegion *MemRegion::getMemorySpace() const {
586 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000587 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000588
Ted Kremenek993f1c72008-10-17 20:28:54 +0000589 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000590 R = SR->getSuperRegion();
591 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000592 }
Mike Stump1eb44332009-09-09 15:08:12 +0000593
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000594 return dyn_cast<MemSpaceRegion>(R);
595}
596
597bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000598 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000599}
Ted Kremenek1670e402009-04-11 00:11:10 +0000600
Ted Kremenekea20cd72009-06-23 18:05:21 +0000601bool MemRegion::hasHeapStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000602 return isa<HeapSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000603}
Ted Kremenek1670e402009-04-11 00:11:10 +0000604
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000605bool MemRegion::hasHeapOrStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000606 const MemSpaceRegion *MS = getMemorySpace();
607 return isa<StackSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000608}
609
610bool MemRegion::hasGlobalsStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000611 return isa<GlobalsSpaceRegion>(getMemorySpace());
Ted Kremenek15086362009-07-02 18:25:09 +0000612}
613
Ted Kremenekdc147262009-07-02 22:02:15 +0000614bool MemRegion::hasParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000615 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000616}
617
Ted Kremenek15086362009-07-02 18:25:09 +0000618bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000619 const MemSpaceRegion *MS = getMemorySpace();
620 return isa<StackArgumentsSpaceRegion>(MS) ||
621 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000622}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000623
Zhongxing Xuadca2712009-11-10 02:37:53 +0000624// getBaseRegion strips away all elements and fields, and get the base region
625// of them.
626const MemRegion *MemRegion::getBaseRegion() const {
627 const MemRegion *R = this;
628 while (true) {
629 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
630 R = ER->getSuperRegion();
631 continue;
632 }
633 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
634 R = FR->getSuperRegion();
635 continue;
636 }
637 break;
638 }
639 return R;
640}
641
Ted Kremenek1670e402009-04-11 00:11:10 +0000642//===----------------------------------------------------------------------===//
643// View handling.
644//===----------------------------------------------------------------------===//
645
Zhongxing Xu479529e2009-11-10 02:17:20 +0000646const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000647 const MemRegion *R = this;
648 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000649 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000650 // FIXME: generalize. Essentially we want to strip away ElementRegions
651 // that were layered on a symbolic region because of casts. We only
652 // want to strip away ElementRegions, however, where the index is 0.
653 SVal index = ER->getIndex();
654 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000655 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000656 R = ER->getSuperRegion();
657 continue;
658 }
659 }
660 }
661 break;
662 }
663 return R;
664}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000665
666// FIXME: Merge with the implementation of the same method in Store.cpp
667static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
668 if (const RecordType *RT = Ty->getAs<RecordType>()) {
669 const RecordDecl *D = RT->getDecl();
670 if (!D->getDefinition(Ctx))
671 return false;
672 }
673
674 return true;
675}
676
677RegionRawOffset ElementRegion::getAsRawOffset() const {
678 int64_t offset = 0;
679 const ElementRegion *ER = this;
680 const MemRegion *superR = NULL;
681 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000682
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000683 // FIXME: Handle multi-dimensional arrays.
684
685 while (ER) {
686 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000687
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000688 // FIXME: generalize to symbolic offsets.
689 SVal index = ER->getIndex();
690 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
691 // Update the offset.
692 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000693
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000694 if (i != 0) {
695 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000696
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000697 // If we are pointing to an incomplete type, go no further.
698 if (!IsCompleteType(C, elemType)) {
699 superR = ER;
700 break;
701 }
Mike Stump1eb44332009-09-09 15:08:12 +0000702
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000703 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
704 offset += (i * size);
705 }
706
707 // Go to the next ElementRegion (if any).
708 ER = dyn_cast<ElementRegion>(superR);
709 continue;
710 }
Mike Stump1eb44332009-09-09 15:08:12 +0000711
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000712 return NULL;
713 }
Mike Stump1eb44332009-09-09 15:08:12 +0000714
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000715 assert(superR && "super region cannot be NULL");
716 return RegionRawOffset(superR, offset);
717}
718
Ted Kremenek42400962009-11-26 02:34:36 +0000719//===----------------------------------------------------------------------===//
720// BlockDataRegion
721//===----------------------------------------------------------------------===//
722
723void BlockDataRegion::LazyInitializeReferencedVars() {
724 if (ReferencedVars)
725 return;
726
Ted Kremenek67d12872009-12-07 22:05:27 +0000727 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000728 AnalysisContext::referenced_decls_iterator I, E;
729 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
730
731 if (I == E) {
732 ReferencedVars = (void*) 0x1;
733 return;
734 }
735
736 MemRegionManager &MemMgr = *getMemRegionManager();
737 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
738 BumpVectorContext BC(A);
739
740 typedef BumpVector<const MemRegion*> VarVec;
741 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000742 new (BV) VarVec(BC, E - I);
Ted Kremenek42400962009-11-26 02:34:36 +0000743
Ted Kremenek67d12872009-12-07 22:05:27 +0000744 for ( ; I != E; ++I) {
745 const VarDecl *VD = *I;
746 const VarRegion *VR = 0;
747
748 if (!VD->getAttr<BlocksAttr>())
749 VR = MemMgr.getVarRegion(VD, this);
750 else {
751 if (LC)
752 VR = MemMgr.getVarRegion(VD, LC);
753 else {
754 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
755 }
756 }
757
758 assert(VR);
759 BV->push_back(VR, BC);
760 }
Ted Kremenek42400962009-11-26 02:34:36 +0000761
762 ReferencedVars = BV;
763}
764
765BlockDataRegion::referenced_vars_iterator
766BlockDataRegion::referenced_vars_begin() const {
767 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
768
769 BumpVector<const MemRegion*> *Vec =
770 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
771
Ted Kremenek81cef582009-12-03 08:09:21 +0000772 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
773 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000774}
775
776BlockDataRegion::referenced_vars_iterator
777BlockDataRegion::referenced_vars_end() const {
778 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
779
780 BumpVector<const MemRegion*> *Vec =
781 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
782
Ted Kremenek81cef582009-12-03 08:09:21 +0000783 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
784 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000785}