 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
67.1% |
139 / 207 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.3% |
191 / 207 |
| |
|
Line Coverage: |
79.8% |
309 / 387 |
| |
 |
|
 |
1 : //== 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 "clang/Analysis/AnalysisContext.h"
17 : #include "clang/Checker/PathSensitive/MemRegion.h"
18 : #include "clang/AST/CharUnits.h"
19 : #include "clang/AST/StmtVisitor.h"
20 : #include "llvm/Support/raw_ostream.h"
21 :
22 : using namespace clang;
23 :
24 : //===----------------------------------------------------------------------===//
25 : // MemRegion Construction.
26 : //===----------------------------------------------------------------------===//
27 :
28 : template<typename RegionTy> struct MemRegionManagerTrait;
29 :
30 : template <typename RegionTy, typename A1>
31 : RegionTy* 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 :
51 : template <typename RegionTy, typename A1>
52 : RegionTy* MemRegionManager::getSubRegion(const A1 a1,
53 19054: const MemRegion *superRegion) {
54 19054: llvm::FoldingSetNodeID ID;
55 19054: RegionTy::ProfileRegion(ID, a1, superRegion);
56 : void* InsertPos;
57 : RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
58 19054: InsertPos));
59 :
1: branch 0 taken
0: branch 1 not taken
1383: branch 2 taken
251: branch 3 taken
2487: branch 4 taken
648: branch 5 taken
86: branch 6 taken
126: branch 7 taken
333: branch 8 taken
112: branch 9 taken
4141: branch 10 taken
9233: branch 11 taken
6: branch 12 taken
4: branch 13 taken
21: branch 14 taken
5: branch 15 taken
207: branch 16 taken
10: branch 17 taken
60 19054: if (!R) {
61 8665: R = (RegionTy*) A.Allocate<RegionTy>();
1: branch 1 taken
0: branch 2 not taken
1383: branch 5 taken
0: branch 6 not taken
2487: branch 9 taken
0: branch 10 not taken
86: branch 13 taken
0: branch 14 not taken
333: branch 17 taken
0: branch 18 not taken
4141: branch 21 taken
0: branch 22 not taken
6: branch 25 taken
0: branch 26 not taken
21: branch 29 taken
0: branch 30 not taken
207: branch 33 taken
0: branch 34 not taken
62 8665: new (R) RegionTy(a1, superRegion);
1: branch 0 taken
0: branch 1 not taken
1383: branch 3 taken
0: branch 4 not taken
2487: branch 6 taken
0: branch 7 not taken
86: branch 9 taken
0: branch 10 not taken
333: branch 12 taken
0: branch 13 not taken
4141: branch 15 taken
0: branch 16 not taken
6: branch 18 taken
0: branch 19 not taken
21: branch 21 taken
0: branch 22 not taken
207: branch 24 taken
0: branch 25 not taken
63 8665: Regions.InsertNode(R, InsertPos);
64 : }
65 :
66 19054: return R;
67 : }
68 :
69 : template <typename RegionTy, typename A1, typename A2>
70 : RegionTy* 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 :
90 : template <typename RegionTy, typename A1, typename A2>
91 : RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
92 80: const MemRegion *superRegion) {
93 :
94 80: llvm::FoldingSetNodeID ID;
95 80: RegionTy::ProfileRegion(ID, a1, a2, superRegion);
96 : void* InsertPos;
97 : RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
98 80: InsertPos));
99 :
66: branch 0 taken
0: branch 1 not taken
14: branch 2 taken
0: branch 3 not taken
100 80: if (!R) {
101 80: R = (RegionTy*) A.Allocate<RegionTy>();
66: branch 1 taken
0: branch 2 not taken
14: branch 5 taken
0: branch 6 not taken
102 80: new (R) RegionTy(a1, a2, superRegion);
66: branch 0 taken
0: branch 1 not taken
14: branch 3 taken
0: branch 4 not taken
103 80: Regions.InsertNode(R, InsertPos);
104 : }
105 :
106 80: return R;
107 : }
108 :
109 : template <typename RegionTy, typename A1, typename A2, typename A3>
110 : RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
111 66: const MemRegion *superRegion) {
112 :
113 66: llvm::FoldingSetNodeID ID;
114 66: RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
115 : void* InsertPos;
116 : RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
117 66: InsertPos));
118 :
66: branch 0 taken
0: branch 1 not taken
119 66: if (!R) {
120 66: R = (RegionTy*) A.Allocate<RegionTy>();
66: branch 1 taken
0: branch 2 not taken
121 66: new (R) RegionTy(a1, a2, a3, superRegion);
66: branch 0 taken
0: branch 1 not taken
122 66: Regions.InsertNode(R, InsertPos);
123 : }
124 :
125 66: return R;
126 : }
127 :
128 : //===----------------------------------------------------------------------===//
129 : // Object destruction.
130 : //===----------------------------------------------------------------------===//
131 :
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
0: branch 7 not taken
132 0: MemRegion::~MemRegion() {}
133 :
134 2138: MemRegionManager::~MemRegionManager() {
135 : // All regions and their data are BumpPtrAllocated. No need to call
136 : // their destructors.
137 2138: }
138 :
139 : //===----------------------------------------------------------------------===//
140 : // Basic methods.
141 : //===----------------------------------------------------------------------===//
142 :
143 0: bool SubRegion::isSubRegionOf(const MemRegion* R) const {
144 0: const MemRegion* r = getSuperRegion();
0: branch 0 not taken
0: branch 1 not taken
145 0: while (r != 0) {
0: branch 0 not taken
0: branch 1 not taken
146 0: if (r == R)
147 0: return true;
0: branch 1 not taken
0: branch 2 not taken
148 0: if (const SubRegion* sr = dyn_cast<SubRegion>(r))
149 0: r = sr->getSuperRegion();
150 : else
151 0: break;
152 : }
153 0: return false;
154 : }
155 :
156 11321: MemRegionManager* SubRegion::getMemRegionManager() const {
157 11321: const SubRegion* r = this;
158 5455: do {
159 16776: const MemRegion *superRegion = r->getSuperRegion();
5455: branch 1 taken
11321: branch 2 taken
160 16776: if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
161 5455: r = sr;
162 : continue;
163 : }
164 11321: return superRegion->getMemRegionManager();
165 : } while (1);
166 : }
167 :
168 19549: const StackFrameContext *VarRegion::getStackFrame() const {
169 19549: const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
18783: branch 0 taken
766: branch 1 taken
170 19549: return SSR ? SSR->getStackFrame() : NULL;
171 : }
172 :
173 : //===----------------------------------------------------------------------===//
174 : // FoldingSet profiling.
175 : //===----------------------------------------------------------------------===//
176 :
177 0: void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
178 0: ID.AddInteger((unsigned)getKind());
179 0: }
180 :
181 0: void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
182 0: ID.AddInteger((unsigned)getKind());
183 0: ID.AddPointer(getStackFrame());
184 0: }
185 :
186 : void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
187 : const StringLiteral* Str,
188 255: const MemRegion* superRegion) {
189 255: ID.AddInteger((unsigned) StringRegionKind);
190 255: ID.AddPointer(Str);
191 255: ID.AddPointer(superRegion);
192 255: }
193 :
194 : void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
195 : const Expr* Ex, unsigned cnt,
196 16: const MemRegion *) {
197 16: ID.AddInteger((unsigned) AllocaRegionKind);
198 16: ID.AddPointer(Ex);
199 16: ID.AddInteger(cnt);
200 16: }
201 :
202 2: void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
203 2: ProfileRegion(ID, Ex, Cnt, superRegion);
204 2: }
205 :
206 5: void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
207 5: CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
208 5: }
209 :
210 : void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
211 : const CompoundLiteralExpr* CL,
212 31: const MemRegion* superRegion) {
213 31: ID.AddInteger((unsigned) CompoundLiteralRegionKind);
214 31: ID.AddPointer(CL);
215 31: ID.AddPointer(superRegion);
216 31: }
217 :
218 : void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
219 : const PointerType *PT,
220 14: const MemRegion *sRegion) {
221 14: ID.AddInteger((unsigned) CXXThisRegionKind);
222 14: ID.AddPointer(PT);
223 14: ID.AddPointer(sRegion);
224 14: }
225 :
226 4: void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
227 4: CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
228 4: }
229 :
230 : void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
231 24012: const MemRegion* superRegion, Kind k) {
232 24012: ID.AddInteger((unsigned) k);
233 24012: ID.AddPointer(D);
234 24012: ID.AddPointer(superRegion);
235 24012: }
236 :
237 278: void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
238 278: DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
239 278: }
240 :
241 9703: void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
242 9703: VarRegion::ProfileRegion(ID, getDecl(), superRegion);
243 9703: }
244 :
245 : void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
246 4067: const MemRegion *sreg) {
247 4067: ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
248 4067: ID.Add(sym);
249 4067: ID.AddPointer(sreg);
250 4067: }
251 :
252 932: void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
253 932: SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
254 932: }
255 :
256 : void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
257 : QualType ElementType, SVal Idx,
258 2340: const MemRegion* superRegion) {
259 2340: ID.AddInteger(MemRegion::ElementRegionKind);
260 2340: ID.Add(ElementType);
261 2340: ID.AddPointer(superRegion);
262 2340: Idx.Profile(ID);
263 2340: }
264 :
265 589: void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
266 589: ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
267 589: }
268 :
269 : void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
270 : const FunctionDecl *FD,
271 1977: const MemRegion*) {
272 1977: ID.AddInteger(MemRegion::FunctionTextRegionKind);
273 1977: ID.AddPointer(FD);
274 1977: }
275 :
276 343: void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
277 343: FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
278 343: }
279 :
280 : void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
281 : const BlockDecl *BD, CanQualType,
282 : const AnalysisContext *AC,
283 68: const MemRegion*) {
284 68: ID.AddInteger(MemRegion::BlockTextRegionKind);
285 68: ID.AddPointer(BD);
286 68: }
287 :
288 2: void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
289 2: BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
290 2: }
291 :
292 : void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
293 : const BlockTextRegion *BC,
294 : const LocationContext *LC,
295 66: const MemRegion *sReg) {
296 66: ID.AddInteger(MemRegion::BlockDataRegionKind);
297 66: ID.AddPointer(BC);
298 66: ID.AddPointer(LC);
299 66: ID.AddPointer(sReg);
300 66: }
301 :
302 0: void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
303 0: BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
304 0: }
305 :
306 : void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
307 : Expr const *Ex,
308 1: const MemRegion *sReg) {
309 1: ID.AddPointer(Ex);
310 1: ID.AddPointer(sReg);
311 1: }
312 :
313 0: void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
314 0: ProfileRegion(ID, Ex, getSuperRegion());
315 0: }
316 :
317 : //===----------------------------------------------------------------------===//
318 : // Region pretty-printing.
319 : //===----------------------------------------------------------------------===//
320 :
321 0: void MemRegion::dump() const {
322 0: dumpToStream(llvm::errs());
323 0: }
324 :
325 92: std::string MemRegion::getString() const {
326 92: std::string s;
327 92: llvm::raw_string_ostream os(s);
328 92: dumpToStream(os);
329 92: return os.str();
330 : }
331 :
332 0: void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
333 0: os << "<Unknown Region>";
334 0: }
335 :
336 0: void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
337 0: os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
338 0: }
339 :
340 0: void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
341 0: os << "code{" << getDecl()->getDeclName().getAsString() << '}';
342 0: }
343 :
344 0: void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
345 0: os << "block_code{" << (void*) this << '}';
346 0: }
347 :
348 0: void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
349 0: os << "block_data{" << BC << '}';
350 0: }
351 :
352 :
353 0: void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
354 : // FIXME: More elaborate pretty-printing.
355 0: os << "{ " << (void*) CL << " }";
356 0: }
357 :
358 0: void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
359 0: os << "this";
360 0: }
361 :
362 0: void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
363 : os << "element{" << superRegion << ','
364 0: << Index << ',' << getElementType().getAsString() << '}';
365 0: }
366 :
367 0: void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
368 0: os << superRegion << "->" << getDecl()->getNameAsString();
369 0: }
370 :
371 0: void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
372 0: os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
373 0: }
374 :
375 0: void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
376 0: Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
377 0: }
378 :
379 0: void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
380 0: os << "SymRegion{" << sym << '}';
381 0: }
382 :
383 92: void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
384 92: os << cast<VarDecl>(D)->getNameAsString();
385 92: }
386 :
387 0: void RegionRawOffset::dump() const {
388 0: dumpToStream(llvm::errs());
389 0: }
390 :
391 0: void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
392 0: os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
393 0: }
394 :
395 : //===----------------------------------------------------------------------===//
396 : // MemRegionManager methods.
397 : //===----------------------------------------------------------------------===//
398 :
399 : template <typename REG>
400 5527: const REG *MemRegionManager::LazyAllocate(REG*& region) {
873: branch 0 taken
827: branch 1 taken
1168: branch 2 taken
1993: branch 3 taken
1993: branch 4 taken
1993: branch 5 taken
308: branch 6 taken
358: branch 7 taken
401 5527: if (!region) {
402 2349: region = (REG*) A.Allocate<REG>();
873: branch 1 taken
0: branch 2 not taken
1168: branch 5 taken
0: branch 6 not taken
0: branch 9 not taken
0: branch 10 not taken
308: branch 13 taken
0: branch 14 not taken
403 2349: new (region) REG(this);
404 : }
405 :
406 5527: return region;
407 : }
408 :
409 : template <typename REG, typename ARG>
410 2545: const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
1107: branch 0 taken
0: branch 1 not taken
1438: branch 2 taken
0: branch 3 not taken
411 2545: if (!region) {
412 2545: region = (REG*) A.Allocate<REG>();
1107: branch 1 taken
0: branch 2 not taken
1438: branch 5 taken
0: branch 6 not taken
413 2545: new (region) REG(this, a);
414 : }
415 :
416 2545: return region;
417 : }
418 :
419 : const StackLocalsSpaceRegion*
420 9089: MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
0: branch 0 not taken
9089: branch 1 taken
421 9089: assert(STC);
7651: branch 0 taken
1438: branch 1 taken
422 9089: if (STC == cachedStackLocalsFrame)
423 7651: return cachedStackLocalsRegion;
424 1438: cachedStackLocalsFrame = STC;
425 1438: return LazyAllocate(cachedStackLocalsRegion, STC);
426 : }
427 :
428 : const StackArgumentsSpaceRegion *
429 3896: MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
0: branch 0 not taken
3896: branch 1 taken
430 3896: assert(STC);
2789: branch 0 taken
1107: branch 1 taken
431 3896: if (STC == cachedStackArgumentsFrame)
432 2789: return cachedStackArgumentsRegion;
433 :
434 1107: cachedStackArgumentsFrame = STC;
435 1107: return LazyAllocate(cachedStackArgumentsRegion, STC);
436 : }
437 :
438 666: const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
439 666: return LazyAllocate(globals);
440 : }
441 :
442 0: const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
443 0: return LazyAllocate(heap);
444 : }
445 :
446 3161: const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
447 3161: return LazyAllocate(unknown);
448 : }
449 :
450 1700: const MemSpaceRegion *MemRegionManager::getCodeRegion() {
451 1700: return LazyAllocate(code);
452 : }
453 :
454 : //===----------------------------------------------------------------------===//
455 : // Constructing regions.
456 : //===----------------------------------------------------------------------===//
457 :
458 217: const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
459 217: return getSubRegion<StringRegion>(Str, getGlobalsRegion());
460 : }
461 :
462 : const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
463 13343: const LocationContext *LC) {
464 13343: const MemRegion *sReg = 0;
465 :
12894: branch 1 taken
449: branch 2 taken
466 13343: if (D->hasLocalStorage()) {
467 : // FIXME: Once we implement scope handling, we will need to properly lookup
468 : // 'D' to the proper LocationContext.
469 12894: const DeclContext *DC = D->getDeclContext();
470 12894: const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
471 :
26: branch 0 taken
12868: branch 1 taken
472 12894: if (!STC)
473 26: sReg = getUnknownRegion();
474 : else {
475 : sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
476 : ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
9827: branch 1 taken
3041: branch 2 taken
845: branch 4 taken
8982: branch 5 taken
477 12868: : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
478 : }
479 : }
480 : else {
481 449: sReg = getGlobalsRegion();
482 : }
483 :
484 13343: return getSubRegion<VarRegion>(D, sReg);
485 : }
486 :
487 : const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
488 31: const MemRegion *superR) {
489 31: return getSubRegion<VarRegion>(D, superR);
490 : }
491 :
492 : const BlockDataRegion *
493 : MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
494 66: const LocationContext *LC) {
495 66: const MemRegion *sReg = 0;
496 :
66: branch 0 taken
0: branch 1 not taken
497 66: if (LC) {
498 : // FIXME: Once we implement scope handling, we want the parent region
499 : // to be the scope.
500 66: const StackFrameContext *STC = LC->getCurrentStackFrame();
0: branch 0 not taken
66: branch 1 taken
501 66: assert(STC);
502 66: sReg = getStackLocalsRegion(STC);
503 : }
504 : else {
505 : // We allow 'LC' to be NULL for cases where want BlockDataRegions
506 : // without context-sensitivity.
507 0: sReg = getUnknownRegion();
508 : }
509 :
510 66: return getSubRegion<BlockDataRegion>(BC, LC, sReg);
511 : }
512 :
513 : const CompoundLiteralRegion*
514 : MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
515 26: const LocationContext *LC) {
516 :
517 26: const MemRegion *sReg = 0;
518 :
0: branch 1 not taken
26: branch 2 taken
519 26: if (CL->isFileScope())
520 0: sReg = getGlobalsRegion();
521 : else {
522 26: const StackFrameContext *STC = LC->getCurrentStackFrame();
0: branch 0 not taken
26: branch 1 taken
523 26: assert(STC);
524 26: sReg = getStackLocalsRegion(STC);
525 : }
526 :
527 26: return getSubRegion<CompoundLiteralRegion>(CL, sReg);
528 : }
529 :
530 : const ElementRegion*
531 : MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
532 : const MemRegion* superRegion,
533 1751: ASTContext& Ctx){
534 :
535 1751: QualType T = Ctx.getCanonicalType(elementType);
536 :
537 1751: llvm::FoldingSetNodeID ID;
538 1751: ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
539 :
540 : void* InsertPos;
541 1751: MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
542 1751: ElementRegion* R = cast_or_null<ElementRegion>(data);
543 :
1332: branch 0 taken
419: branch 1 taken
544 1751: if (!R) {
545 1332: R = (ElementRegion*) A.Allocate<ElementRegion>();
1332: branch 1 taken
0: branch 2 not taken
546 1332: new (R) ElementRegion(T, Idx, superRegion);
1332: branch 0 taken
0: branch 1 not taken
547 1332: Regions.InsertNode(R, InsertPos);
548 : }
549 :
550 1751: return R;
551 : }
552 :
553 : const FunctionTextRegion *
554 1634: MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
555 1634: return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
556 : }
557 :
558 : const BlockTextRegion *
559 : MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
560 66: AnalysisContext *AC) {
561 66: return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
562 : }
563 :
564 :
565 : /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
566 3135: const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
567 3135: return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
568 : }
569 :
570 : const FieldRegion*
571 : MemRegionManager::getFieldRegion(const FieldDecl* d,
572 445: const MemRegion* superRegion){
573 445: return getSubRegion<FieldRegion>(d, superRegion);
574 : }
575 :
576 : const ObjCIvarRegion*
577 : MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
578 212: const MemRegion* superRegion) {
579 212: return getSubRegion<ObjCIvarRegion>(d, superRegion);
580 : }
581 :
582 : const CXXObjectRegion*
583 : MemRegionManager::getCXXObjectRegion(Expr const *E,
584 1: LocationContext const *LC) {
585 1: const StackFrameContext *SFC = LC->getCurrentStackFrame();
0: branch 0 not taken
1: branch 1 taken
586 1: assert(SFC);
587 1: return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
588 : }
589 :
590 : const CXXThisRegion*
591 : MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
592 10: const LocationContext *LC) {
593 10: const StackFrameContext *STC = LC->getCurrentStackFrame();
0: branch 0 not taken
10: branch 1 taken
594 10: assert(STC);
595 10: const PointerType *PT = thisPointerTy->getAs<PointerType>();
0: branch 0 not taken
10: branch 1 taken
596 10: assert(PT);
597 10: return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
598 : }
599 :
600 : const AllocaRegion*
601 : MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
602 14: const LocationContext *LC) {
603 14: const StackFrameContext *STC = LC->getCurrentStackFrame();
0: branch 0 not taken
14: branch 1 taken
604 14: assert(STC);
605 14: return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
606 : }
607 :
608 27522: const MemSpaceRegion *MemRegion::getMemorySpace() const {
609 27522: const MemRegion *R = this;
610 27522: const SubRegion* SR = dyn_cast<SubRegion>(this);
611 :
28338: branch 0 taken
27522: branch 1 taken
612 83382: while (SR) {
613 28338: R = SR->getSuperRegion();
614 28338: SR = dyn_cast<SubRegion>(R);
615 : }
616 :
617 27522: return dyn_cast<MemSpaceRegion>(R);
618 : }
619 :
620 4235: bool MemRegion::hasStackStorage() const {
621 4235: return isa<StackSpaceRegion>(getMemorySpace());
622 : }
623 :
624 395: bool MemRegion::hasStackNonParametersStorage() const {
625 395: return isa<StackLocalsSpaceRegion>(getMemorySpace());
626 : }
627 :
628 0: bool MemRegion::hasStackParametersStorage() const {
629 0: return isa<StackArgumentsSpaceRegion>(getMemorySpace());
630 : }
631 :
632 1488: bool MemRegion::hasGlobalsOrParametersStorage() const {
633 1488: const MemSpaceRegion *MS = getMemorySpace();
634 : return isa<StackArgumentsSpaceRegion>(MS) ||
987: branch 1 taken
501: branch 2 taken
60: branch 4 taken
927: branch 5 taken
635 1488: isa<GlobalsSpaceRegion>(MS);
636 : }
637 :
638 : // getBaseRegion strips away all elements and fields, and get the base region
639 : // of them.
640 1194: const MemRegion *MemRegion::getBaseRegion() const {
641 1194: const MemRegion *R = this;
642 212: while (true) {
177: branch 1 taken
1229: branch 2 taken
643 1406: if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
644 177: R = ER->getSuperRegion();
645 177: continue;
646 : }
35: branch 1 taken
1194: branch 2 taken
647 1229: if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
648 35: R = FR->getSuperRegion();
649 35: continue;
650 : }
651 : break;
652 : }
653 1194: return R;
654 : }
655 :
656 : //===----------------------------------------------------------------------===//
657 : // View handling.
658 : //===----------------------------------------------------------------------===//
659 :
660 28162: const MemRegion *MemRegion::StripCasts() const {
661 28162: const MemRegion *R = this;
662 1613: while (true) {
2511: branch 1 taken
27264: branch 2 taken
663 29775: if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
664 : // 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 2511: SVal index = ER->getIndex();
2277: branch 1 taken
234: branch 2 taken
668 2511: if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
1613: branch 2 taken
664: branch 3 taken
669 2277: if (CI->getValue().getSExtValue() == 0) {
670 1613: R = ER->getSuperRegion();
671 : continue;
672 : }
898: branch 1 taken
1613: branch 2 taken
673 2511: }
674 : }
675 : break;
676 : }
677 28162: return R;
678 : }
679 :
680 : // FIXME: Merge with the implementation of the same method in Store.cpp
681 1028: static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
58: branch 2 taken
970: branch 3 taken
682 1028: if (const RecordType *RT = Ty->getAs<RecordType>()) {
683 58: const RecordDecl *D = RT->getDecl();
0: branch 1 not taken
58: branch 2 taken
684 58: if (!D->getDefinition(Ctx))
685 0: return false;
686 : }
687 :
688 1028: return true;
689 : }
690 :
691 3154: RegionRawOffset ElementRegion::getAsRawOffset() const {
692 3154: CharUnits offset = CharUnits::Zero();
693 3154: const ElementRegion *ER = this;
694 3154: const MemRegion *superR = NULL;
695 3154: ASTContext &C = getContext();
696 :
697 : // FIXME: Handle multi-dimensional arrays.
698 :
0: branch 1 not taken
2714: branch 2 taken
448: branch 3 taken
3162: branch 4 taken
2706: branch 5 taken
699 12184: while (ER) {
700 3162: superR = ER->getSuperRegion();
701 :
702 : // FIXME: generalize to symbolic offsets.
703 3162: SVal index = ER->getIndex();
2714: branch 1 taken
448: branch 2 taken
704 3162: if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
705 : // Update the offset.
706 2714: int64_t i = CI->getValue().getSExtValue();
707 :
1028: branch 0 taken
1686: branch 1 taken
708 2714: if (i != 0) {
709 1028: QualType elemType = ER->getElementType();
710 :
711 : // If we are pointing to an incomplete type, go no further.
0: branch 1 not taken
1028: branch 2 taken
712 1028: if (!IsCompleteType(C, elemType)) {
713 0: superR = ER;
714 0: break;
715 : }
716 :
717 1028: CharUnits size = C.getTypeSizeInChars(elemType);
718 1028: offset += (i * size);
719 : }
720 :
721 : // Go to the next ElementRegion (if any).
722 2714: ER = dyn_cast<ElementRegion>(superR);
723 2714: continue;
724 : }
725 :
726 896: return NULL;
727 : }
728 :
0: branch 0 not taken
2706: branch 1 taken
729 2706: assert(superR && "super region cannot be NULL");
730 2706: return RegionRawOffset(superR, offset.getQuantity());
731 : }
732 :
733 : //===----------------------------------------------------------------------===//
734 : // BlockDataRegion
735 : //===----------------------------------------------------------------------===//
736 :
737 252: void BlockDataRegion::LazyInitializeReferencedVars() {
192: branch 0 taken
60: branch 1 taken
738 252: if (ReferencedVars)
739 192: return;
740 :
741 60: AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
742 : AnalysisContext::referenced_decls_iterator I, E;
743 60: llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
744 :
6: branch 0 taken
54: branch 1 taken
745 60: if (I == E) {
746 6: ReferencedVars = (void*) 0x1;
747 6: return;
748 : }
749 :
750 54: MemRegionManager &MemMgr = *getMemRegionManager();
751 54: llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
752 54: BumpVectorContext BC(A);
753 :
754 : typedef BumpVector<const MemRegion*> VarVec;
755 54: VarVec *BV = (VarVec*) A.Allocate<VarVec>();
54: branch 1 taken
0: branch 2 not taken
756 54: new (BV) VarVec(BC, E - I);
757 :
76: branch 0 taken
54: branch 1 taken
758 130: for ( ; I != E; ++I) {
759 76: const VarDecl *VD = *I;
760 76: const VarRegion *VR = 0;
761 :
36: branch 1 taken
40: branch 2 taken
31: branch 4 taken
5: branch 5 taken
31: branch 6 taken
45: branch 7 taken
762 76: if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
763 31: VR = MemMgr.getVarRegion(VD, this);
764 : else {
45: branch 0 taken
0: branch 1 not taken
765 45: if (LC)
766 45: VR = MemMgr.getVarRegion(VD, LC);
767 : else {
768 0: VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
769 : }
770 : }
771 :
0: branch 0 not taken
76: branch 1 taken
772 76: assert(VR);
773 76: BV->push_back(VR, BC);
774 : }
775 :
776 54: ReferencedVars = BV;
777 : }
778 :
779 : BlockDataRegion::referenced_vars_iterator
780 126: BlockDataRegion::referenced_vars_begin() const {
781 126: const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
782 :
783 : BumpVector<const MemRegion*> *Vec =
784 126: static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
785 :
786 : return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
119: branch 0 taken
7: branch 1 taken
787 126: NULL : Vec->begin());
788 : }
789 :
790 : BlockDataRegion::referenced_vars_iterator
791 126: BlockDataRegion::referenced_vars_end() const {
792 126: const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
793 :
794 : BumpVector<const MemRegion*> *Vec =
795 126: static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
796 :
797 : return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
119: branch 0 taken
7: branch 1 taken
798 126: NULL : Vec->end());
799 : }
Generated: 2010-02-10 01:31 by zcov