blob: 194015a11b1158cbab684b3300f304653aada0f6 [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/Analysis/AnalysisContext.h"
17#include "clang/Checker/PathSensitive/MemRegion.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000018#include "clang/AST/CharUnits.h"
Ted Kremenek42400962009-11-26 02:34:36 +000019#include "clang/AST/StmtVisitor.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 {
368 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000369}
370
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000371void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
372 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
373}
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 {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000384 os << cast<VarDecl>(D)->getNameAsString();
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);
422 if (STC == cachedStackLocalsFrame)
423 return cachedStackLocalsRegion;
424 cachedStackLocalsFrame = STC;
425 return LazyAllocate(cachedStackLocalsRegion, STC);
Ted Kremenekd05552a2009-07-02 18:14:59 +0000426}
427
Ted Kremenek67d12872009-12-07 22:05:27 +0000428const StackArgumentsSpaceRegion *
429MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000430 assert(STC);
431 if (STC == cachedStackArgumentsFrame)
432 return cachedStackArgumentsRegion;
433
434 cachedStackArgumentsFrame = STC;
435 return LazyAllocate(cachedStackArgumentsRegion, STC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000436}
437
438const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000439 return LazyAllocate(globals);
440}
441
Ted Kremenek67d12872009-12-07 22:05:27 +0000442const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000443 return LazyAllocate(heap);
444}
445
Ted Kremenekb48ad642009-12-04 00:26:31 +0000446const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000447 return LazyAllocate(unknown);
448}
449
Ted Kremenekb48ad642009-12-04 00:26:31 +0000450const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000451 return LazyAllocate(code);
452}
453
Ted Kremenek25010132009-06-22 23:13:13 +0000454//===----------------------------------------------------------------------===//
455// Constructing regions.
456//===----------------------------------------------------------------------===//
457
Ted Kremenekb48ad642009-12-04 00:26:31 +0000458const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000459 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000460}
461
Ted Kremenekb48ad642009-12-04 00:26:31 +0000462const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
463 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000464 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000465
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000466 if (D->hasLocalStorage()) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000467 // FIXME: Once we implement scope handling, we will need to properly lookup
468 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000469 const DeclContext *DC = D->getDeclContext();
470 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000471
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000472 if (!STC)
473 sReg = getUnknownRegion();
474 else {
475 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
476 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
477 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
478 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000479 }
480 else {
481 sReg = getGlobalsRegion();
482 }
483
484 return getSubRegion<VarRegion>(D, sReg);
485}
486
487const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
488 const MemRegion *superR) {
489 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000490}
491
Ted Kremenekb48ad642009-12-04 00:26:31 +0000492const BlockDataRegion *
493MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
494 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000495 const MemRegion *sReg = 0;
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000496
Ted Kremenek67d12872009-12-07 22:05:27 +0000497 if (LC) {
498 // FIXME: Once we implement scope handling, we want the parent region
499 // to be the scope.
500 const StackFrameContext *STC = LC->getCurrentStackFrame();
501 assert(STC);
502 sReg = getStackLocalsRegion(STC);
503 }
504 else {
505 // We allow 'LC' to be NULL for cases where want BlockDataRegions
506 // without context-sensitivity.
507 sReg = getUnknownRegion();
508 }
509
510 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000511}
512
Ted Kremenekb48ad642009-12-04 00:26:31 +0000513const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000514MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
515 const LocationContext *LC) {
516
517 const MemRegion *sReg = 0;
518
519 if (CL->isFileScope())
520 sReg = getGlobalsRegion();
521 else {
522 const StackFrameContext *STC = LC->getCurrentStackFrame();
523 assert(STC);
524 sReg = getStackLocalsRegion(STC);
525 }
526
527 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000528}
529
Ted Kremenekb48ad642009-12-04 00:26:31 +0000530const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000531MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000532 const MemRegion* superRegion,
533 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000534
535 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000536
Zhongxing Xu511191c2008-10-21 05:27:10 +0000537 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000538 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000539
540 void* InsertPos;
541 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
542 ElementRegion* R = cast_or_null<ElementRegion>(data);
543
544 if (!R) {
545 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000546 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000547 Regions.InsertNode(R, InsertPos);
548 }
549
550 return R;
551}
552
Ted Kremenekb48ad642009-12-04 00:26:31 +0000553const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000554MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000555 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000556}
557
Ted Kremenekb48ad642009-12-04 00:26:31 +0000558const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000559MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
560 AnalysisContext *AC) {
561 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000562}
563
564
Ted Kremenek993f1c72008-10-17 20:28:54 +0000565/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000566const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000567 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000568}
569
Ted Kremenekde0d2632010-01-05 02:18:06 +0000570const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000571MemRegionManager::getFieldRegion(const FieldDecl* d,
572 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000573 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000574}
575
Ted Kremenekb48ad642009-12-04 00:26:31 +0000576const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000577MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
578 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000579 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000580}
581
Ted Kremenekde0d2632010-01-05 02:18:06 +0000582const CXXObjectRegion*
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000583MemRegionManager::getCXXObjectRegion(Expr const *E,
584 LocationContext const *LC) {
585 const StackFrameContext *SFC = LC->getCurrentStackFrame();
586 assert(SFC);
587 return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000588}
589
Ted Kremenekde0d2632010-01-05 02:18:06 +0000590const CXXThisRegion*
591MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
592 const LocationContext *LC) {
593 const StackFrameContext *STC = LC->getCurrentStackFrame();
594 assert(STC);
595 const PointerType *PT = thisPointerTy->getAs<PointerType>();
596 assert(PT);
597 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
598}
599
Ted Kremenekb48ad642009-12-04 00:26:31 +0000600const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000601MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
602 const LocationContext *LC) {
603 const StackFrameContext *STC = LC->getCurrentStackFrame();
604 assert(STC);
605 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000606}
607
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000608const MemSpaceRegion *MemRegion::getMemorySpace() const {
609 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000610 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000611
Ted Kremenek993f1c72008-10-17 20:28:54 +0000612 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000613 R = SR->getSuperRegion();
614 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000615 }
Mike Stump1eb44332009-09-09 15:08:12 +0000616
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000617 return dyn_cast<MemSpaceRegion>(R);
618}
619
620bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000621 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000622}
Ted Kremenek1670e402009-04-11 00:11:10 +0000623
Ted Kremenekde0d2632010-01-05 02:18:06 +0000624bool MemRegion::hasStackNonParametersStorage() const {
625 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000626}
Ted Kremenek1670e402009-04-11 00:11:10 +0000627
Ted Kremenekde0d2632010-01-05 02:18:06 +0000628bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000629 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000630}
631
Ted Kremenek15086362009-07-02 18:25:09 +0000632bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000633 const MemSpaceRegion *MS = getMemorySpace();
634 return isa<StackArgumentsSpaceRegion>(MS) ||
635 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000636}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000637
Zhongxing Xuadca2712009-11-10 02:37:53 +0000638// getBaseRegion strips away all elements and fields, and get the base region
639// of them.
640const MemRegion *MemRegion::getBaseRegion() const {
641 const MemRegion *R = this;
642 while (true) {
643 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
644 R = ER->getSuperRegion();
645 continue;
646 }
647 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
648 R = FR->getSuperRegion();
649 continue;
650 }
651 break;
652 }
653 return R;
654}
655
Ted Kremenek1670e402009-04-11 00:11:10 +0000656//===----------------------------------------------------------------------===//
657// View handling.
658//===----------------------------------------------------------------------===//
659
Zhongxing Xu479529e2009-11-10 02:17:20 +0000660const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000661 const MemRegion *R = this;
662 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000663 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000664 // FIXME: generalize. Essentially we want to strip away ElementRegions
665 // that were layered on a symbolic region because of casts. We only
666 // want to strip away ElementRegions, however, where the index is 0.
667 SVal index = ER->getIndex();
668 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000669 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000670 R = ER->getSuperRegion();
671 continue;
672 }
673 }
674 }
675 break;
676 }
677 return R;
678}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000679
680// FIXME: Merge with the implementation of the same method in Store.cpp
681static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
682 if (const RecordType *RT = Ty->getAs<RecordType>()) {
683 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000684 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000685 return false;
686 }
687
688 return true;
689}
690
691RegionRawOffset ElementRegion::getAsRawOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000692 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000693 const ElementRegion *ER = this;
694 const MemRegion *superR = NULL;
695 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000696
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000697 // FIXME: Handle multi-dimensional arrays.
698
699 while (ER) {
700 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000701
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000702 // FIXME: generalize to symbolic offsets.
703 SVal index = ER->getIndex();
704 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
705 // Update the offset.
706 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000707
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000708 if (i != 0) {
709 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000710
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000711 // If we are pointing to an incomplete type, go no further.
712 if (!IsCompleteType(C, elemType)) {
713 superR = ER;
714 break;
715 }
Mike Stump1eb44332009-09-09 15:08:12 +0000716
Ken Dyck199c3d62010-01-11 17:06:35 +0000717 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000718 offset += (i * size);
719 }
720
721 // Go to the next ElementRegion (if any).
722 ER = dyn_cast<ElementRegion>(superR);
723 continue;
724 }
Mike Stump1eb44332009-09-09 15:08:12 +0000725
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000726 return NULL;
727 }
Mike Stump1eb44332009-09-09 15:08:12 +0000728
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000729 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000730 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000731}
732
Ted Kremenek42400962009-11-26 02:34:36 +0000733//===----------------------------------------------------------------------===//
734// BlockDataRegion
735//===----------------------------------------------------------------------===//
736
737void BlockDataRegion::LazyInitializeReferencedVars() {
738 if (ReferencedVars)
739 return;
740
Ted Kremenek67d12872009-12-07 22:05:27 +0000741 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000742 AnalysisContext::referenced_decls_iterator I, E;
743 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
744
745 if (I == E) {
746 ReferencedVars = (void*) 0x1;
747 return;
748 }
749
750 MemRegionManager &MemMgr = *getMemRegionManager();
751 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
752 BumpVectorContext BC(A);
753
754 typedef BumpVector<const MemRegion*> VarVec;
755 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000756 new (BV) VarVec(BC, E - I);
Ted Kremenek42400962009-11-26 02:34:36 +0000757
Ted Kremenek67d12872009-12-07 22:05:27 +0000758 for ( ; I != E; ++I) {
759 const VarDecl *VD = *I;
760 const VarRegion *VR = 0;
761
Ted Kremenek85248732010-02-06 00:30:00 +0000762 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000763 VR = MemMgr.getVarRegion(VD, this);
764 else {
765 if (LC)
766 VR = MemMgr.getVarRegion(VD, LC);
767 else {
768 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
769 }
770 }
771
772 assert(VR);
773 BV->push_back(VR, BC);
774 }
Ted Kremenek42400962009-11-26 02:34:36 +0000775
776 ReferencedVars = BV;
777}
778
779BlockDataRegion::referenced_vars_iterator
780BlockDataRegion::referenced_vars_begin() const {
781 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
782
783 BumpVector<const MemRegion*> *Vec =
784 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
785
Ted Kremenek81cef582009-12-03 08:09:21 +0000786 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
787 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000788}
789
790BlockDataRegion::referenced_vars_iterator
791BlockDataRegion::referenced_vars_end() const {
792 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
793
794 BumpVector<const MemRegion*> *Vec =
795 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
796
Ted Kremenek81cef582009-12-03 08:09:21 +0000797 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
798 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000799}