blob: da45c4dfee067ee20364967e98d412068d7112c5 [file] [log] [blame]
Ted Kremenek5ca90a22008-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 Kremenek1f22aa72009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenek608677a2009-08-21 23:25:54 +000019#include "clang/Analysis/PathSensitive/AnalysisContext.h"
Ted Kremenek3378b612009-11-26 02:34:36 +000020#include "clang/AST/StmtVisitor.h"
Ted Kremenek5ca90a22008-10-04 05:50:14 +000021
22using namespace clang;
23
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +000024//===----------------------------------------------------------------------===//
Ted Kremenek0ecd4c72009-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 Kremenek04af9f22009-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 Kremenek0ecd4c72009-12-04 00:05:57 +0000123 }
Ted Kremenek04af9f22009-12-07 22:05:27 +0000124
125 return R;
126}
Ted Kremenek0ecd4c72009-12-04 00:05:57 +0000127
128//===----------------------------------------------------------------------===//
Ted Kremenek3378b612009-11-26 02:34:36 +0000129// Object destruction.
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000130//===----------------------------------------------------------------------===//
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000131
132MemRegion::~MemRegion() {}
133
Ted Kremenek3378b612009-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 Xu550c1c42009-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 Kremenekfb87e302009-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 Kremenek5ca90a22008-10-04 05:50:14 +0000168void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
169 ID.AddInteger((unsigned)getKind());
170}
171
Ted Kremenek04af9f22009-12-07 22:05:27 +0000172void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
173 ID.AddInteger((unsigned)getKind());
174 ID.AddPointer(getStackFrame());
175}
176
Mike Stump11289f42009-09-09 15:08:12 +0000177void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
178 const StringLiteral* Str,
Zhongxing Xud1aac352008-10-25 14:13:41 +0000179 const MemRegion* superRegion) {
180 ID.AddInteger((unsigned) StringRegionKind);
181 ID.AddPointer(Str);
182 ID.AddPointer(superRegion);
183}
184
Ted Kremenek16783cf2008-11-02 00:34:33 +0000185void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek8bae3002009-06-23 00:15:41 +0000186 const Expr* Ex, unsigned cnt,
187 const MemRegion *) {
Ted Kremenek16783cf2008-11-02 00:34:33 +0000188 ID.AddInteger((unsigned) AllocaRegionKind);
189 ID.AddPointer(Ex);
190 ID.AddInteger(cnt);
191}
192
193void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek8bae3002009-06-23 00:15:41 +0000194 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek16783cf2008-11-02 00:34:33 +0000195}
196
Ted Kremenekbc48caf2008-10-27 20:57:58 +0000197void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
198 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
199}
200
201void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
202 const CompoundLiteralExpr* CL,
203 const MemRegion* superRegion) {
204 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
205 ID.AddPointer(CL);
206 ID.AddPointer(superRegion);
207}
208
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000209void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
210 const MemRegion* superRegion, Kind k) {
211 ID.AddInteger((unsigned) k);
212 ID.AddPointer(D);
213 ID.AddPointer(superRegion);
214}
215
216void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
217 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
218}
219
Ted Kremenek14536f62009-08-21 22:28:32 +0000220void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000221 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenek14536f62009-08-21 22:28:32 +0000222}
223
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000224void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
225 const MemRegion *sreg) {
Ted Kremenek8b103c62008-10-17 20:28:54 +0000226 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek3cb81db2008-12-05 02:39:38 +0000227 ID.Add(sym);
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000228 ID.AddPointer(sreg);
Ted Kremenek8b103c62008-10-17 20:28:54 +0000229}
230
231void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000232 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek8b103c62008-10-17 20:28:54 +0000233}
234
Ted Kremenek02e50892009-05-04 06:18:28 +0000235void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump11289f42009-09-09 15:08:12 +0000236 QualType ElementType, SVal Idx,
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000237 const MemRegion* superRegion) {
238 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenek02e50892009-05-04 06:18:28 +0000239 ID.Add(ElementType);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000240 ID.AddPointer(superRegion);
241 Idx.Profile(ID);
242}
243
244void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek02e50892009-05-04 06:18:28 +0000245 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000246}
Zhongxing Xu7b700572008-10-27 13:17:02 +0000247
Ted Kremenek10a50e72009-11-25 01:32:22 +0000248void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
249 const FunctionDecl *FD,
250 const MemRegion*) {
251 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenek198a8c52009-08-28 04:49:15 +0000252 ID.AddPointer(FD);
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000253}
254
Ted Kremenek10a50e72009-11-25 01:32:22 +0000255void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
256 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
257}
258
259void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek04af9f22009-12-07 22:05:27 +0000260 const BlockDecl *BD, CanQualType,
261 const AnalysisContext *AC,
262 const MemRegion*) {
Ted Kremenek10a50e72009-11-25 01:32:22 +0000263 ID.AddInteger(MemRegion::BlockTextRegionKind);
264 ID.AddPointer(BD);
265}
266
267void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000268 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000269}
270
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000271void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
272 const BlockTextRegion *BC,
273 const LocationContext *LC,
Ted Kremenek04af9f22009-12-07 22:05:27 +0000274 const MemRegion *sReg) {
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000275 ID.AddInteger(MemRegion::BlockDataRegionKind);
276 ID.AddPointer(BC);
277 ID.AddPointer(LC);
Ted Kremenek04af9f22009-12-07 22:05:27 +0000278 ID.AddPointer(sReg);
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000279}
280
281void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000282 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000283}
284
Zhongxing Xu9103df12009-02-05 06:57:29 +0000285//===----------------------------------------------------------------------===//
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000286// Region pretty-printing.
287//===----------------------------------------------------------------------===//
288
Ted Kremenekeabdd982009-07-13 23:31:04 +0000289void MemRegion::dump() const {
290 dumpToStream(llvm::errs());
Ted Kremenekdf15d292009-07-02 17:24:10 +0000291}
292
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000293std::string MemRegion::getString() const {
294 std::string s;
295 llvm::raw_string_ostream os(s);
Ted Kremenekeabdd982009-07-13 23:31:04 +0000296 dumpToStream(os);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000297 return os.str();
298}
299
Ted Kremenekeabdd982009-07-13 23:31:04 +0000300void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000301 os << "<Unknown Region>";
302}
303
Ted Kremenekeabdd982009-07-13 23:31:04 +0000304void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek16783cf2008-11-02 00:34:33 +0000305 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
306}
307
Ted Kremenek10a50e72009-11-25 01:32:22 +0000308void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek198a8c52009-08-28 04:49:15 +0000309 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek9bb660c2009-04-21 19:56:58 +0000310}
311
Ted Kremenek10a50e72009-11-25 01:32:22 +0000312void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000313 os << "block_code{" << (void*) this << '}';
Ted Kremenek10a50e72009-11-25 01:32:22 +0000314}
315
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000316void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
317 os << "block_data{" << BC << '}';
318}
319
320
Ted Kremenekeabdd982009-07-13 23:31:04 +0000321void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7421c012009-04-21 18:09:22 +0000322 // FIXME: More elaborate pretty-printing.
323 os << "{ " << (void*) CL << " }";
324}
325
Ted Kremenekeabdd982009-07-13 23:31:04 +0000326void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000327 os << "element{" << superRegion << ','
328 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek7421c012009-04-21 18:09:22 +0000329}
330
Ted Kremenekeabdd982009-07-13 23:31:04 +0000331void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
332 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek7421c012009-04-21 18:09:22 +0000333}
334
Ted Kremenek291e8f72009-07-19 20:36:24 +0000335void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
336 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
337}
338
Mike Stump11289f42009-09-09 15:08:12 +0000339void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7d3a3342009-07-19 20:38:24 +0000340 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek7421c012009-04-21 18:09:22 +0000341}
342
Ted Kremenekeabdd982009-07-13 23:31:04 +0000343void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekc8d67462009-07-13 23:38:57 +0000344 os << "SymRegion{" << sym << '}';
Ted Kremenek7421c012009-04-21 18:09:22 +0000345}
346
Ted Kremenekeabdd982009-07-13 23:31:04 +0000347void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattnerf3d3fae2008-11-24 05:29:24 +0000348 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000349}
350
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000351void RegionRawOffset::dump() const {
352 dumpToStream(llvm::errs());
353}
354
355void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
356 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
357}
358
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000359//===----------------------------------------------------------------------===//
360// MemRegionManager methods.
361//===----------------------------------------------------------------------===//
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000362
Ted Kremenek04af9f22009-12-07 22:05:27 +0000363template <typename REG>
364const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump11289f42009-09-09 15:08:12 +0000365 if (!region) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000366 region = (REG*) A.Allocate<REG>();
367 new (region) REG(this);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000368 }
Ted Kremenekfb87e302009-06-23 00:46:41 +0000369
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000370 return region;
371}
372
Ted Kremenek04af9f22009-12-07 22:05:27 +0000373template <typename REG, typename ARG>
374const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
375 if (!region) {
376 region = (REG*) A.Allocate<REG>();
377 new (region) REG(this, a);
378 }
379
380 return region;
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000381}
382
Ted Kremenek04af9f22009-12-07 22:05:27 +0000383const StackLocalsSpaceRegion*
Ted Kremenekf6d9ceb2009-12-11 06:43:27 +0000384MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
385 assert(STC);
386 if (STC == cachedStackLocalsFrame)
387 return cachedStackLocalsRegion;
388 cachedStackLocalsFrame = STC;
389 return LazyAllocate(cachedStackLocalsRegion, STC);
Ted Kremenek7e4a9a02009-07-02 18:14:59 +0000390}
391
Ted Kremenek04af9f22009-12-07 22:05:27 +0000392const StackArgumentsSpaceRegion *
393MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenekf6d9ceb2009-12-11 06:43:27 +0000394 assert(STC);
395 if (STC == cachedStackArgumentsFrame)
396 return cachedStackArgumentsRegion;
397
398 cachedStackArgumentsFrame = STC;
399 return LazyAllocate(cachedStackArgumentsRegion, STC);
Ted Kremenek04af9f22009-12-07 22:05:27 +0000400}
401
402const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000403 return LazyAllocate(globals);
404}
405
Ted Kremenek04af9f22009-12-07 22:05:27 +0000406const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000407 return LazyAllocate(heap);
408}
409
Ted Kremenek721fcc02009-12-04 00:26:31 +0000410const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xud9959ae2008-10-08 02:50:44 +0000411 return LazyAllocate(unknown);
412}
413
Ted Kremenek721fcc02009-12-04 00:26:31 +0000414const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000415 return LazyAllocate(code);
416}
417
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000418//===----------------------------------------------------------------------===//
419// Constructing regions.
420//===----------------------------------------------------------------------===//
421
Ted Kremenek721fcc02009-12-04 00:26:31 +0000422const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000423 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xud1aac352008-10-25 14:13:41 +0000424}
425
Ted Kremenek721fcc02009-12-04 00:26:31 +0000426const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
427 const LocationContext *LC) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000428 const MemRegion *sReg = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000429
Ted Kremenekf6d9ceb2009-12-11 06:43:27 +0000430 if (D->hasLocalStorage()) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000431 // FIXME: Once we implement scope handling, we will need to properly lookup
432 // 'D' to the proper LocationContext.
Ted Kremenekf6d9ceb2009-12-11 06:43:27 +0000433 const DeclContext *DC = D->getDeclContext();
434 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump11289f42009-09-09 15:08:12 +0000435
Ted Kremenekf6d9ceb2009-12-11 06:43:27 +0000436 if (!STC)
437 sReg = getUnknownRegion();
438 else {
439 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
440 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
441 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
442 }
Ted Kremenek04af9f22009-12-07 22:05:27 +0000443 }
444 else {
445 sReg = getGlobalsRegion();
446 }
447
448 return getSubRegion<VarRegion>(D, sReg);
449}
450
451const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
452 const MemRegion *superR) {
453 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000454}
455
Ted Kremenek721fcc02009-12-04 00:26:31 +0000456const BlockDataRegion *
457MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
458 const LocationContext *LC) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000459 const MemRegion *sReg = 0;
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000460
Ted Kremenek04af9f22009-12-07 22:05:27 +0000461 if (LC) {
462 // FIXME: Once we implement scope handling, we want the parent region
463 // to be the scope.
464 const StackFrameContext *STC = LC->getCurrentStackFrame();
465 assert(STC);
466 sReg = getStackLocalsRegion(STC);
467 }
468 else {
469 // We allow 'LC' to be NULL for cases where want BlockDataRegions
470 // without context-sensitivity.
471 sReg = getUnknownRegion();
472 }
473
474 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000475}
476
Ted Kremenek721fcc02009-12-04 00:26:31 +0000477const CompoundLiteralRegion*
Ted Kremenek04af9f22009-12-07 22:05:27 +0000478MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
479 const LocationContext *LC) {
480
481 const MemRegion *sReg = 0;
482
483 if (CL->isFileScope())
484 sReg = getGlobalsRegion();
485 else {
486 const StackFrameContext *STC = LC->getCurrentStackFrame();
487 assert(STC);
488 sReg = getStackLocalsRegion(STC);
489 }
490
491 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenekbc48caf2008-10-27 20:57:58 +0000492}
493
Ted Kremenek721fcc02009-12-04 00:26:31 +0000494const ElementRegion*
Ted Kremenek02e50892009-05-04 06:18:28 +0000495MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenekc7b1dad2009-07-16 01:33:37 +0000496 const MemRegion* superRegion,
497 ASTContext& Ctx){
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000498
499 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekf065b152008-12-13 19:24:37 +0000500
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000501 llvm::FoldingSetNodeID ID;
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000502 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000503
504 void* InsertPos;
505 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
506 ElementRegion* R = cast_or_null<ElementRegion>(data);
507
508 if (!R) {
509 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000510 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000511 Regions.InsertNode(R, InsertPos);
512 }
513
514 return R;
515}
516
Ted Kremenek721fcc02009-12-04 00:26:31 +0000517const FunctionTextRegion *
Ted Kremenek10a50e72009-11-25 01:32:22 +0000518MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000519 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000520}
521
Ted Kremenek721fcc02009-12-04 00:26:31 +0000522const BlockTextRegion *
Ted Kremenek04af9f22009-12-07 22:05:27 +0000523MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
524 AnalysisContext *AC) {
525 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenek10a50e72009-11-25 01:32:22 +0000526}
527
528
Ted Kremenek8b103c62008-10-17 20:28:54 +0000529/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenek721fcc02009-12-04 00:26:31 +0000530const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000531 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek8b103c62008-10-17 20:28:54 +0000532}
533
Ted Kremenek721fcc02009-12-04 00:26:31 +0000534const FieldRegion *
535MemRegionManager::getFieldRegion(const FieldDecl* d,
536 const MemRegion* superRegion){
Ted Kremenekda98f732009-07-10 16:51:45 +0000537 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000538}
539
Ted Kremenek721fcc02009-12-04 00:26:31 +0000540const ObjCIvarRegion*
Ted Kremenek8b103c62008-10-17 20:28:54 +0000541MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
542 const MemRegion* superRegion) {
Ted Kremenekda98f732009-07-10 16:51:45 +0000543 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000544}
545
Ted Kremenek721fcc02009-12-04 00:26:31 +0000546const ObjCObjectRegion*
Ted Kremenek8921d932008-10-24 20:30:08 +0000547MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenek22666402009-06-23 00:04:09 +0000548 const MemRegion* superRegion) {
Ted Kremenekda98f732009-07-10 16:51:45 +0000549 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremenek8921d932008-10-24 20:30:08 +0000550}
551
Ted Kremenek721fcc02009-12-04 00:26:31 +0000552const AllocaRegion*
Ted Kremenek04af9f22009-12-07 22:05:27 +0000553MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
554 const LocationContext *LC) {
555 const StackFrameContext *STC = LC->getCurrentStackFrame();
556 assert(STC);
557 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek16783cf2008-11-02 00:34:33 +0000558}
559
Ted Kremenek2d99f972009-06-23 18:17:08 +0000560const MemSpaceRegion *MemRegion::getMemorySpace() const {
561 const MemRegion *R = this;
Ted Kremenek404b1322009-06-23 18:05:21 +0000562 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump11289f42009-09-09 15:08:12 +0000563
Ted Kremenek8b103c62008-10-17 20:28:54 +0000564 while (SR) {
Ted Kremenek2d99f972009-06-23 18:17:08 +0000565 R = SR->getSuperRegion();
566 SR = dyn_cast<SubRegion>(R);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000567 }
Mike Stump11289f42009-09-09 15:08:12 +0000568
Ted Kremenek2d99f972009-06-23 18:17:08 +0000569 return dyn_cast<MemSpaceRegion>(R);
570}
571
572bool MemRegion::hasStackStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000573 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000574}
Ted Kremenekdf240002009-04-11 00:11:10 +0000575
Ted Kremenek404b1322009-06-23 18:05:21 +0000576bool MemRegion::hasHeapStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000577 return isa<HeapSpaceRegion>(getMemorySpace());
Zhongxing Xu1a195b22009-06-23 02:51:21 +0000578}
Ted Kremenekdf240002009-04-11 00:11:10 +0000579
Ted Kremenek2d99f972009-06-23 18:17:08 +0000580bool MemRegion::hasHeapOrStackStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000581 const MemSpaceRegion *MS = getMemorySpace();
582 return isa<StackSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS);
Ted Kremenekdf67d422009-07-02 18:25:09 +0000583}
584
585bool MemRegion::hasGlobalsStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000586 return isa<GlobalsSpaceRegion>(getMemorySpace());
Ted Kremenekdf67d422009-07-02 18:25:09 +0000587}
588
Ted Kremenek725b4a32009-07-02 22:02:15 +0000589bool MemRegion::hasParametersStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000590 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenek725b4a32009-07-02 22:02:15 +0000591}
592
Ted Kremenekdf67d422009-07-02 18:25:09 +0000593bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek04af9f22009-12-07 22:05:27 +0000594 const MemSpaceRegion *MS = getMemorySpace();
595 return isa<StackArgumentsSpaceRegion>(MS) ||
596 isa<GlobalsSpaceRegion>(MS);
Ted Kremenekdf67d422009-07-02 18:25:09 +0000597}
Ted Kremenek2d99f972009-06-23 18:17:08 +0000598
Zhongxing Xu80bbc6d2009-11-10 02:37:53 +0000599// getBaseRegion strips away all elements and fields, and get the base region
600// of them.
601const MemRegion *MemRegion::getBaseRegion() const {
602 const MemRegion *R = this;
603 while (true) {
604 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
605 R = ER->getSuperRegion();
606 continue;
607 }
608 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
609 R = FR->getSuperRegion();
610 continue;
611 }
612 break;
613 }
614 return R;
615}
616
Ted Kremenekdf240002009-04-11 00:11:10 +0000617//===----------------------------------------------------------------------===//
618// View handling.
619//===----------------------------------------------------------------------===//
620
Zhongxing Xuf8f3f9d2009-11-10 02:17:20 +0000621const MemRegion *MemRegion::StripCasts() const {
Ted Kremenekccf33352009-07-29 18:14:27 +0000622 const MemRegion *R = this;
623 while (true) {
Mike Stump11289f42009-09-09 15:08:12 +0000624 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenekccf33352009-07-29 18:14:27 +0000625 // FIXME: generalize. Essentially we want to strip away ElementRegions
626 // that were layered on a symbolic region because of casts. We only
627 // want to strip away ElementRegions, however, where the index is 0.
628 SVal index = ER->getIndex();
629 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000630 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenekccf33352009-07-29 18:14:27 +0000631 R = ER->getSuperRegion();
632 continue;
633 }
634 }
635 }
636 break;
637 }
638 return R;
639}
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000640
641// FIXME: Merge with the implementation of the same method in Store.cpp
642static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
643 if (const RecordType *RT = Ty->getAs<RecordType>()) {
644 const RecordDecl *D = RT->getDecl();
645 if (!D->getDefinition(Ctx))
646 return false;
647 }
648
649 return true;
650}
651
652RegionRawOffset ElementRegion::getAsRawOffset() const {
653 int64_t offset = 0;
654 const ElementRegion *ER = this;
655 const MemRegion *superR = NULL;
656 ASTContext &C = getContext();
Mike Stump11289f42009-09-09 15:08:12 +0000657
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000658 // FIXME: Handle multi-dimensional arrays.
659
660 while (ER) {
661 superR = ER->getSuperRegion();
Mike Stump11289f42009-09-09 15:08:12 +0000662
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000663 // FIXME: generalize to symbolic offsets.
664 SVal index = ER->getIndex();
665 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
666 // Update the offset.
667 int64_t i = CI->getValue().getSExtValue();
Mike Stump11289f42009-09-09 15:08:12 +0000668
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000669 if (i != 0) {
670 QualType elemType = ER->getElementType();
Mike Stump11289f42009-09-09 15:08:12 +0000671
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000672 // If we are pointing to an incomplete type, go no further.
673 if (!IsCompleteType(C, elemType)) {
674 superR = ER;
675 break;
676 }
Mike Stump11289f42009-09-09 15:08:12 +0000677
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000678 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
679 offset += (i * size);
680 }
681
682 // Go to the next ElementRegion (if any).
683 ER = dyn_cast<ElementRegion>(superR);
684 continue;
685 }
Mike Stump11289f42009-09-09 15:08:12 +0000686
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000687 return NULL;
688 }
Mike Stump11289f42009-09-09 15:08:12 +0000689
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000690 assert(superR && "super region cannot be NULL");
691 return RegionRawOffset(superR, offset);
692}
693
Ted Kremenek3378b612009-11-26 02:34:36 +0000694//===----------------------------------------------------------------------===//
695// BlockDataRegion
696//===----------------------------------------------------------------------===//
697
698void BlockDataRegion::LazyInitializeReferencedVars() {
699 if (ReferencedVars)
700 return;
701
Ted Kremenek04af9f22009-12-07 22:05:27 +0000702 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek3378b612009-11-26 02:34:36 +0000703 AnalysisContext::referenced_decls_iterator I, E;
704 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
705
706 if (I == E) {
707 ReferencedVars = (void*) 0x1;
708 return;
709 }
710
711 MemRegionManager &MemMgr = *getMemRegionManager();
712 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
713 BumpVectorContext BC(A);
714
715 typedef BumpVector<const MemRegion*> VarVec;
716 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek117e4722009-12-01 22:12:34 +0000717 new (BV) VarVec(BC, E - I);
Ted Kremenek3378b612009-11-26 02:34:36 +0000718
Ted Kremenek04af9f22009-12-07 22:05:27 +0000719 for ( ; I != E; ++I) {
720 const VarDecl *VD = *I;
721 const VarRegion *VR = 0;
722
723 if (!VD->getAttr<BlocksAttr>())
724 VR = MemMgr.getVarRegion(VD, this);
725 else {
726 if (LC)
727 VR = MemMgr.getVarRegion(VD, LC);
728 else {
729 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
730 }
731 }
732
733 assert(VR);
734 BV->push_back(VR, BC);
735 }
Ted Kremenek3378b612009-11-26 02:34:36 +0000736
737 ReferencedVars = BV;
738}
739
740BlockDataRegion::referenced_vars_iterator
741BlockDataRegion::referenced_vars_begin() const {
742 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
743
744 BumpVector<const MemRegion*> *Vec =
745 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
746
Ted Kremenek4a815fc2009-12-03 08:09:21 +0000747 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
748 NULL : Vec->begin());
Ted Kremenek3378b612009-11-26 02:34:36 +0000749}
750
751BlockDataRegion::referenced_vars_iterator
752BlockDataRegion::referenced_vars_end() const {
753 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
754
755 BumpVector<const MemRegion*> *Vec =
756 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
757
Ted Kremenek4a815fc2009-12-03 08:09:21 +0000758 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
759 NULL : Vec->end());
Ted Kremenek3378b612009-11-26 02:34:36 +0000760}