MemRegion.cpp revision 24570c4c258545f8310e4bc96503a5668982cf67
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/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
17#include "clang/AST/Attr.h"
18#include "clang/AST/CharUnits.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/RecordLayout.h"
21#include "clang/Analysis/AnalysisContext.h"
22#include "clang/Analysis/Support/BumpVector.h"
23#include "clang/Basic/SourceManager.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
25#include "llvm/Support/raw_ostream.h"
26
27using namespace clang;
28using namespace ento;
29
30//===----------------------------------------------------------------------===//
31// MemRegion Construction.
32//===----------------------------------------------------------------------===//
33
34template<typename RegionTy> struct MemRegionManagerTrait;
35
36template <typename RegionTy, typename A1>
37RegionTy* MemRegionManager::getRegion(const A1 a1) {
38
39  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
40  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
41
42  llvm::FoldingSetNodeID ID;
43  RegionTy::ProfileRegion(ID, a1, superRegion);
44  void *InsertPos;
45  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
46                                                                   InsertPos));
47
48  if (!R) {
49    R = (RegionTy*) A.Allocate<RegionTy>();
50    new (R) RegionTy(a1, superRegion);
51    Regions.InsertNode(R, InsertPos);
52  }
53
54  return R;
55}
56
57template <typename RegionTy, typename A1>
58RegionTy* MemRegionManager::getSubRegion(const A1 a1,
59                                         const MemRegion *superRegion) {
60  llvm::FoldingSetNodeID ID;
61  RegionTy::ProfileRegion(ID, a1, superRegion);
62  void *InsertPos;
63  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
64                                                                   InsertPos));
65
66  if (!R) {
67    R = (RegionTy*) A.Allocate<RegionTy>();
68    new (R) RegionTy(a1, superRegion);
69    Regions.InsertNode(R, InsertPos);
70  }
71
72  return R;
73}
74
75template <typename RegionTy, typename A1, typename A2>
76RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
77
78  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
79  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
80
81  llvm::FoldingSetNodeID ID;
82  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
83  void *InsertPos;
84  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
85                                                                   InsertPos));
86
87  if (!R) {
88    R = (RegionTy*) A.Allocate<RegionTy>();
89    new (R) RegionTy(a1, a2, superRegion);
90    Regions.InsertNode(R, InsertPos);
91  }
92
93  return R;
94}
95
96template <typename RegionTy, typename A1, typename A2>
97RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
98                                         const MemRegion *superRegion) {
99
100  llvm::FoldingSetNodeID ID;
101  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
102  void *InsertPos;
103  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
104                                                                   InsertPos));
105
106  if (!R) {
107    R = (RegionTy*) A.Allocate<RegionTy>();
108    new (R) RegionTy(a1, a2, superRegion);
109    Regions.InsertNode(R, InsertPos);
110  }
111
112  return R;
113}
114
115template <typename RegionTy, typename A1, typename A2, typename A3>
116RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
117                                         const MemRegion *superRegion) {
118
119  llvm::FoldingSetNodeID ID;
120  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
121  void *InsertPos;
122  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
123                                                                   InsertPos));
124
125  if (!R) {
126    R = (RegionTy*) A.Allocate<RegionTy>();
127    new (R) RegionTy(a1, a2, a3, superRegion);
128    Regions.InsertNode(R, InsertPos);
129  }
130
131  return R;
132}
133
134//===----------------------------------------------------------------------===//
135// Object destruction.
136//===----------------------------------------------------------------------===//
137
138MemRegion::~MemRegion() {}
139
140MemRegionManager::~MemRegionManager() {
141  // All regions and their data are BumpPtrAllocated.  No need to call
142  // their destructors.
143}
144
145//===----------------------------------------------------------------------===//
146// Basic methods.
147//===----------------------------------------------------------------------===//
148
149bool SubRegion::isSubRegionOf(const MemRegion* R) const {
150  const MemRegion* r = getSuperRegion();
151  while (r != 0) {
152    if (r == R)
153      return true;
154    if (const SubRegion* sr = dyn_cast<SubRegion>(r))
155      r = sr->getSuperRegion();
156    else
157      break;
158  }
159  return false;
160}
161
162MemRegionManager* SubRegion::getMemRegionManager() const {
163  const SubRegion* r = this;
164  do {
165    const MemRegion *superRegion = r->getSuperRegion();
166    if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
167      r = sr;
168      continue;
169    }
170    return superRegion->getMemRegionManager();
171  } while (1);
172}
173
174const StackFrameContext *VarRegion::getStackFrame() const {
175  const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
176  return SSR ? SSR->getStackFrame() : NULL;
177}
178
179//===----------------------------------------------------------------------===//
180// Region extents.
181//===----------------------------------------------------------------------===//
182
183DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
184  ASTContext &Ctx = svalBuilder.getContext();
185  QualType T = getDesugaredValueType(Ctx);
186
187  if (isa<VariableArrayType>(T))
188    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
189  if (isa<IncompleteArrayType>(T))
190    return UnknownVal();
191
192  CharUnits size = Ctx.getTypeSizeInChars(T);
193  QualType sizeTy = svalBuilder.getArrayIndexType();
194  return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
195}
196
197DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
198  DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
199
200  // A zero-length array at the end of a struct often stands for dynamically-
201  // allocated extra memory.
202  if (Extent.isZeroConstant()) {
203    QualType T = getDesugaredValueType(svalBuilder.getContext());
204
205    if (isa<ConstantArrayType>(T))
206      return UnknownVal();
207  }
208
209  return Extent;
210}
211
212DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
213  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
214}
215
216DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
217  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
218}
219
220DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
221  return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
222                                svalBuilder.getArrayIndexType());
223}
224
225ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
226  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
227
228const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
229  return cast<ObjCIvarDecl>(D);
230}
231
232QualType ObjCIvarRegion::getValueType() const {
233  return getDecl()->getType();
234}
235
236QualType CXXBaseObjectRegion::getValueType() const {
237  return QualType(decl->getTypeForDecl(), 0);
238}
239
240//===----------------------------------------------------------------------===//
241// FoldingSet profiling.
242//===----------------------------------------------------------------------===//
243
244void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
245  ID.AddInteger((unsigned)getKind());
246}
247
248void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
249  ID.AddInteger((unsigned)getKind());
250  ID.AddPointer(getStackFrame());
251}
252
253void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
254  ID.AddInteger((unsigned)getKind());
255  ID.AddPointer(getCodeRegion());
256}
257
258void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
259                                 const StringLiteral* Str,
260                                 const MemRegion* superRegion) {
261  ID.AddInteger((unsigned) StringRegionKind);
262  ID.AddPointer(Str);
263  ID.AddPointer(superRegion);
264}
265
266void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
267                                     const ObjCStringLiteral* Str,
268                                     const MemRegion* superRegion) {
269  ID.AddInteger((unsigned) ObjCStringRegionKind);
270  ID.AddPointer(Str);
271  ID.AddPointer(superRegion);
272}
273
274void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
275                                 const Expr *Ex, unsigned cnt,
276                                 const MemRegion *superRegion) {
277  ID.AddInteger((unsigned) AllocaRegionKind);
278  ID.AddPointer(Ex);
279  ID.AddInteger(cnt);
280  ID.AddPointer(superRegion);
281}
282
283void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
284  ProfileRegion(ID, Ex, Cnt, superRegion);
285}
286
287void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
288  CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
289}
290
291void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
292                                          const CompoundLiteralExpr *CL,
293                                          const MemRegion* superRegion) {
294  ID.AddInteger((unsigned) CompoundLiteralRegionKind);
295  ID.AddPointer(CL);
296  ID.AddPointer(superRegion);
297}
298
299void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
300                                  const PointerType *PT,
301                                  const MemRegion *sRegion) {
302  ID.AddInteger((unsigned) CXXThisRegionKind);
303  ID.AddPointer(PT);
304  ID.AddPointer(sRegion);
305}
306
307void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
308  CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
309}
310
311void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
312                                   const ObjCIvarDecl *ivd,
313                                   const MemRegion* superRegion) {
314  DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
315}
316
317void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
318                               const MemRegion* superRegion, Kind k) {
319  ID.AddInteger((unsigned) k);
320  ID.AddPointer(D);
321  ID.AddPointer(superRegion);
322}
323
324void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
325  DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
326}
327
328void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
329  VarRegion::ProfileRegion(ID, getDecl(), superRegion);
330}
331
332void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
333                                   const MemRegion *sreg) {
334  ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
335  ID.Add(sym);
336  ID.AddPointer(sreg);
337}
338
339void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
340  SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
341}
342
343void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
344                                  QualType ElementType, SVal Idx,
345                                  const MemRegion* superRegion) {
346  ID.AddInteger(MemRegion::ElementRegionKind);
347  ID.Add(ElementType);
348  ID.AddPointer(superRegion);
349  Idx.Profile(ID);
350}
351
352void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
353  ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
354}
355
356void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
357                                       const NamedDecl *FD,
358                                       const MemRegion*) {
359  ID.AddInteger(MemRegion::FunctionTextRegionKind);
360  ID.AddPointer(FD);
361}
362
363void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
364  FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
365}
366
367void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
368                                    const BlockDecl *BD, CanQualType,
369                                    const AnalysisDeclContext *AC,
370                                    const MemRegion*) {
371  ID.AddInteger(MemRegion::BlockTextRegionKind);
372  ID.AddPointer(BD);
373}
374
375void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
376  BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
377}
378
379void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
380                                    const BlockTextRegion *BC,
381                                    const LocationContext *LC,
382                                    const MemRegion *sReg) {
383  ID.AddInteger(MemRegion::BlockDataRegionKind);
384  ID.AddPointer(BC);
385  ID.AddPointer(LC);
386  ID.AddPointer(sReg);
387}
388
389void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
390  BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
391}
392
393void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
394                                        Expr const *Ex,
395                                        const MemRegion *sReg) {
396  ID.AddPointer(Ex);
397  ID.AddPointer(sReg);
398}
399
400void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
401  ProfileRegion(ID, Ex, getSuperRegion());
402}
403
404void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
405                                        const CXXRecordDecl *decl,
406                                        const MemRegion *sReg) {
407  ID.AddPointer(decl);
408  ID.AddPointer(sReg);
409}
410
411void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
412  ProfileRegion(ID, decl, superRegion);
413}
414
415//===----------------------------------------------------------------------===//
416// Region anchors.
417//===----------------------------------------------------------------------===//
418
419void GlobalsSpaceRegion::anchor() { }
420void HeapSpaceRegion::anchor() { }
421void UnknownSpaceRegion::anchor() { }
422void StackLocalsSpaceRegion::anchor() { }
423void StackArgumentsSpaceRegion::anchor() { }
424void TypedRegion::anchor() { }
425void TypedValueRegion::anchor() { }
426void CodeTextRegion::anchor() { }
427void SubRegion::anchor() { }
428
429//===----------------------------------------------------------------------===//
430// Region pretty-printing.
431//===----------------------------------------------------------------------===//
432
433void MemRegion::dump() const {
434  dumpToStream(llvm::errs());
435}
436
437std::string MemRegion::getString() const {
438  std::string s;
439  llvm::raw_string_ostream os(s);
440  dumpToStream(os);
441  return os.str();
442}
443
444void MemRegion::dumpToStream(raw_ostream &os) const {
445  os << "<Unknown Region>";
446}
447
448void AllocaRegion::dumpToStream(raw_ostream &os) const {
449  os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
450}
451
452void FunctionTextRegion::dumpToStream(raw_ostream &os) const {
453  os << "code{" << getDecl()->getDeclName().getAsString() << '}';
454}
455
456void BlockTextRegion::dumpToStream(raw_ostream &os) const {
457  os << "block_code{" << (const void*) this << '}';
458}
459
460void BlockDataRegion::dumpToStream(raw_ostream &os) const {
461  os << "block_data{" << BC << '}';
462}
463
464void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
465  // FIXME: More elaborate pretty-printing.
466  os << "{ " << (const void*) CL <<  " }";
467}
468
469void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
470  os << "temp_object{" << getValueType().getAsString() << ','
471     << (const void*) Ex << '}';
472}
473
474void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
475  os << "base{" << superRegion << ',' << decl->getName() << '}';
476}
477
478void CXXThisRegion::dumpToStream(raw_ostream &os) const {
479  os << "this";
480}
481
482void ElementRegion::dumpToStream(raw_ostream &os) const {
483  os << "element{" << superRegion << ','
484     << Index << ',' << getElementType().getAsString() << '}';
485}
486
487void FieldRegion::dumpToStream(raw_ostream &os) const {
488  os << superRegion << "->" << *getDecl();
489}
490
491void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
492  os << "ivar{" << superRegion << ',' << *getDecl() << '}';
493}
494
495void StringRegion::dumpToStream(raw_ostream &os) const {
496  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
497}
498
499void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
500  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
501}
502
503void SymbolicRegion::dumpToStream(raw_ostream &os) const {
504  os << "SymRegion{" << sym << '}';
505}
506
507void VarRegion::dumpToStream(raw_ostream &os) const {
508  os << *cast<VarDecl>(D);
509}
510
511void RegionRawOffset::dump() const {
512  dumpToStream(llvm::errs());
513}
514
515void RegionRawOffset::dumpToStream(raw_ostream &os) const {
516  os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
517}
518
519void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
520  os << "StaticGlobalsMemSpace{" << CR << '}';
521}
522
523void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
524  os << "GlobalInternalSpaceRegion";
525}
526
527void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
528  os << "GlobalSystemSpaceRegion";
529}
530
531void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
532  os << "GlobalImmutableSpaceRegion";
533}
534
535void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
536  os << "HeapSpaceRegion";
537}
538
539void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
540  os << "UnknownSpaceRegion";
541}
542
543void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
544  os << "StackArgumentsSpaceRegion";
545}
546
547void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
548  os << "StackLocalsSpaceRegion";
549}
550
551bool MemRegion::canPrintPretty() const {
552  return false;
553}
554
555void MemRegion::printPretty(raw_ostream &os) const {
556  return;
557}
558
559bool VarRegion::canPrintPretty() const {
560  return true;
561}
562
563void VarRegion::printPretty(raw_ostream &os) const {
564  os << getDecl()->getName();
565}
566
567bool FieldRegion::canPrintPretty() const {
568  return superRegion->canPrintPretty();
569}
570
571void FieldRegion::printPretty(raw_ostream &os) const {
572  superRegion->printPretty(os);
573  os << "." << getDecl()->getName();
574}
575
576//===----------------------------------------------------------------------===//
577// MemRegionManager methods.
578//===----------------------------------------------------------------------===//
579
580template <typename REG>
581const REG *MemRegionManager::LazyAllocate(REG*& region) {
582  if (!region) {
583    region = (REG*) A.Allocate<REG>();
584    new (region) REG(this);
585  }
586
587  return region;
588}
589
590template <typename REG, typename ARG>
591const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
592  if (!region) {
593    region = (REG*) A.Allocate<REG>();
594    new (region) REG(this, a);
595  }
596
597  return region;
598}
599
600const StackLocalsSpaceRegion*
601MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
602  assert(STC);
603  StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
604
605  if (R)
606    return R;
607
608  R = A.Allocate<StackLocalsSpaceRegion>();
609  new (R) StackLocalsSpaceRegion(this, STC);
610  return R;
611}
612
613const StackArgumentsSpaceRegion *
614MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
615  assert(STC);
616  StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
617
618  if (R)
619    return R;
620
621  R = A.Allocate<StackArgumentsSpaceRegion>();
622  new (R) StackArgumentsSpaceRegion(this, STC);
623  return R;
624}
625
626const GlobalsSpaceRegion
627*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
628                                    const CodeTextRegion *CR) {
629  if (!CR) {
630    if (K == MemRegion::GlobalSystemSpaceRegionKind)
631      return LazyAllocate(SystemGlobals);
632    if (K == MemRegion::GlobalImmutableSpaceRegionKind)
633      return LazyAllocate(ImmutableGlobals);
634    assert(K == MemRegion::GlobalInternalSpaceRegionKind);
635    return LazyAllocate(InternalGlobals);
636  }
637
638  assert(K == MemRegion::StaticGlobalSpaceRegionKind);
639  StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
640  if (R)
641    return R;
642
643  R = A.Allocate<StaticGlobalSpaceRegion>();
644  new (R) StaticGlobalSpaceRegion(this, CR);
645  return R;
646}
647
648const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
649  return LazyAllocate(heap);
650}
651
652const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
653  return LazyAllocate(unknown);
654}
655
656const MemSpaceRegion *MemRegionManager::getCodeRegion() {
657  return LazyAllocate(code);
658}
659
660//===----------------------------------------------------------------------===//
661// Constructing regions.
662//===----------------------------------------------------------------------===//
663const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
664  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
665}
666
667const ObjCStringRegion *
668MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
669  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
670}
671
672/// Look through a chain of LocationContexts to either find the
673/// StackFrameContext that matches a DeclContext, or find a VarRegion
674/// for a variable captured by a block.
675static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
676getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
677                                      const DeclContext *DC,
678                                      const VarDecl *VD) {
679  while (LC) {
680    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
681      if (cast<DeclContext>(SFC->getDecl()) == DC)
682        return SFC;
683    }
684    if (const BlockInvocationContext *BC =
685        dyn_cast<BlockInvocationContext>(LC)) {
686      const BlockDataRegion *BR =
687        static_cast<const BlockDataRegion*>(BC->getContextData());
688      // FIXME: This can be made more efficient.
689      for (BlockDataRegion::referenced_vars_iterator
690           I = BR->referenced_vars_begin(),
691           E = BR->referenced_vars_end(); I != E; ++I) {
692        if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
693          if (VR->getDecl() == VD)
694            return cast<VarRegion>(I.getCapturedRegion());
695      }
696    }
697
698    LC = LC->getParent();
699  }
700  return (const StackFrameContext*)0;
701}
702
703const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
704                                                const LocationContext *LC) {
705  const MemRegion *sReg = 0;
706
707  if (D->hasGlobalStorage() && !D->isStaticLocal()) {
708
709    // First handle the globals defined in system headers.
710    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
711      // Whitelist the system globals which often DO GET modified, assume the
712      // rest are immutable.
713      if (D->getName().find("errno") != StringRef::npos)
714        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
715      else
716        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
717
718    // Treat other globals as GlobalInternal unless they are constants.
719    } else {
720      QualType GQT = D->getType();
721      const Type *GT = GQT.getTypePtrOrNull();
722      // TODO: We could walk the complex types here and see if everything is
723      // constified.
724      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
725        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
726      else
727        sReg = getGlobalsRegion();
728    }
729
730  // Finally handle static locals.
731  } else {
732    // FIXME: Once we implement scope handling, we will need to properly lookup
733    // 'D' to the proper LocationContext.
734    const DeclContext *DC = D->getDeclContext();
735    llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
736      getStackOrCaptureRegionForDeclContext(LC, DC, D);
737
738    if (V.is<const VarRegion*>())
739      return V.get<const VarRegion*>();
740
741    const StackFrameContext *STC = V.get<const StackFrameContext*>();
742
743    if (!STC)
744      sReg = getUnknownRegion();
745    else {
746      if (D->hasLocalStorage()) {
747        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
748               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
749               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
750      }
751      else {
752        assert(D->isStaticLocal());
753        const Decl *STCD = STC->getDecl();
754        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
755          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
756                                  getFunctionTextRegion(cast<NamedDecl>(STCD)));
757        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
758          const BlockTextRegion *BTR =
759            getBlockTextRegion(BD,
760                     C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
761                     STC->getAnalysisDeclContext());
762          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
763                                  BTR);
764        }
765        else {
766          sReg = getGlobalsRegion();
767        }
768      }
769    }
770  }
771
772  return getSubRegion<VarRegion>(D, sReg);
773}
774
775const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
776                                                const MemRegion *superR) {
777  return getSubRegion<VarRegion>(D, superR);
778}
779
780const BlockDataRegion *
781MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
782                                     const LocationContext *LC) {
783  const MemRegion *sReg = 0;
784  const BlockDecl *BD = BC->getDecl();
785  if (!BD->hasCaptures()) {
786    // This handles 'static' blocks.
787    sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
788  }
789  else {
790    if (LC) {
791      // FIXME: Once we implement scope handling, we want the parent region
792      // to be the scope.
793      const StackFrameContext *STC = LC->getCurrentStackFrame();
794      assert(STC);
795      sReg = getStackLocalsRegion(STC);
796    }
797    else {
798      // We allow 'LC' to be NULL for cases where want BlockDataRegions
799      // without context-sensitivity.
800      sReg = getUnknownRegion();
801    }
802  }
803
804  return getSubRegion<BlockDataRegion>(BC, LC, sReg);
805}
806
807const CompoundLiteralRegion*
808MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
809                                           const LocationContext *LC) {
810
811  const MemRegion *sReg = 0;
812
813  if (CL->isFileScope())
814    sReg = getGlobalsRegion();
815  else {
816    const StackFrameContext *STC = LC->getCurrentStackFrame();
817    assert(STC);
818    sReg = getStackLocalsRegion(STC);
819  }
820
821  return getSubRegion<CompoundLiteralRegion>(CL, sReg);
822}
823
824const ElementRegion*
825MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
826                                   const MemRegion* superRegion,
827                                   ASTContext &Ctx){
828
829  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
830
831  llvm::FoldingSetNodeID ID;
832  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
833
834  void *InsertPos;
835  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
836  ElementRegion* R = cast_or_null<ElementRegion>(data);
837
838  if (!R) {
839    R = (ElementRegion*) A.Allocate<ElementRegion>();
840    new (R) ElementRegion(T, Idx, superRegion);
841    Regions.InsertNode(R, InsertPos);
842  }
843
844  return R;
845}
846
847const FunctionTextRegion *
848MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
849  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
850}
851
852const BlockTextRegion *
853MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
854                                     AnalysisDeclContext *AC) {
855  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
856}
857
858
859/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
860const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
861  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
862}
863
864const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
865  return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
866}
867
868const FieldRegion*
869MemRegionManager::getFieldRegion(const FieldDecl *d,
870                                 const MemRegion* superRegion){
871  return getSubRegion<FieldRegion>(d, superRegion);
872}
873
874const ObjCIvarRegion*
875MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
876                                    const MemRegion* superRegion) {
877  return getSubRegion<ObjCIvarRegion>(d, superRegion);
878}
879
880const CXXTempObjectRegion*
881MemRegionManager::getCXXTempObjectRegion(Expr const *E,
882                                         LocationContext const *LC) {
883  const StackFrameContext *SFC = LC->getCurrentStackFrame();
884  assert(SFC);
885  return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
886}
887
888const CXXBaseObjectRegion *
889MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl,
890                                         const MemRegion *superRegion) {
891  // Check that the base class is actually a direct base of this region.
892  if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(superRegion)) {
893    if (const CXXRecordDecl *Class = TVR->getValueType()->getAsCXXRecordDecl()){
894      if (Class->isVirtuallyDerivedFrom(decl)) {
895        // Virtual base regions should not be layered, since the layout rules
896        // are different.
897        while (const CXXBaseObjectRegion *Base =
898                 dyn_cast<CXXBaseObjectRegion>(superRegion)) {
899          superRegion = Base->getSuperRegion();
900        }
901        assert(superRegion && !isa<MemSpaceRegion>(superRegion));
902
903      } else {
904        // Non-virtual bases should always be direct bases.
905#ifndef NDEBUG
906        bool FoundBase = false;
907        for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
908                                                      E = Class->bases_end();
909             I != E; ++I) {
910          if (I->getType()->getAsCXXRecordDecl() == decl) {
911            FoundBase = true;
912            break;
913          }
914        }
915
916        assert(FoundBase && "Not a direct base class of this region");
917#endif
918      }
919    }
920  }
921
922  return getSubRegion<CXXBaseObjectRegion>(decl, superRegion);
923}
924
925const CXXThisRegion*
926MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
927                                   const LocationContext *LC) {
928  const StackFrameContext *STC = LC->getCurrentStackFrame();
929  assert(STC);
930  const PointerType *PT = thisPointerTy->getAs<PointerType>();
931  assert(PT);
932  return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
933}
934
935const AllocaRegion*
936MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
937                                  const LocationContext *LC) {
938  const StackFrameContext *STC = LC->getCurrentStackFrame();
939  assert(STC);
940  return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
941}
942
943const MemSpaceRegion *MemRegion::getMemorySpace() const {
944  const MemRegion *R = this;
945  const SubRegion* SR = dyn_cast<SubRegion>(this);
946
947  while (SR) {
948    R = SR->getSuperRegion();
949    SR = dyn_cast<SubRegion>(R);
950  }
951
952  return dyn_cast<MemSpaceRegion>(R);
953}
954
955bool MemRegion::hasStackStorage() const {
956  return isa<StackSpaceRegion>(getMemorySpace());
957}
958
959bool MemRegion::hasStackNonParametersStorage() const {
960  return isa<StackLocalsSpaceRegion>(getMemorySpace());
961}
962
963bool MemRegion::hasStackParametersStorage() const {
964  return isa<StackArgumentsSpaceRegion>(getMemorySpace());
965}
966
967bool MemRegion::hasGlobalsOrParametersStorage() const {
968  const MemSpaceRegion *MS = getMemorySpace();
969  return isa<StackArgumentsSpaceRegion>(MS) ||
970         isa<GlobalsSpaceRegion>(MS);
971}
972
973// getBaseRegion strips away all elements and fields, and get the base region
974// of them.
975const MemRegion *MemRegion::getBaseRegion() const {
976  const MemRegion *R = this;
977  while (true) {
978    switch (R->getKind()) {
979      case MemRegion::ElementRegionKind:
980      case MemRegion::FieldRegionKind:
981      case MemRegion::ObjCIvarRegionKind:
982      case MemRegion::CXXBaseObjectRegionKind:
983        R = cast<SubRegion>(R)->getSuperRegion();
984        continue;
985      default:
986        break;
987    }
988    break;
989  }
990  return R;
991}
992
993bool MemRegion::isSubRegionOf(const MemRegion *R) const {
994  return false;
995}
996
997//===----------------------------------------------------------------------===//
998// View handling.
999//===----------------------------------------------------------------------===//
1000
1001const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
1002  const MemRegion *R = this;
1003  while (true) {
1004    switch (R->getKind()) {
1005    case ElementRegionKind: {
1006      const ElementRegion *ER = cast<ElementRegion>(R);
1007      if (!ER->getIndex().isZeroConstant())
1008        return R;
1009      R = ER->getSuperRegion();
1010      break;
1011    }
1012    case CXXBaseObjectRegionKind:
1013      if (!StripBaseCasts)
1014        return R;
1015      R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
1016      break;
1017    default:
1018      return R;
1019    }
1020  }
1021}
1022
1023// FIXME: Merge with the implementation of the same method in Store.cpp
1024static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
1025  if (const RecordType *RT = Ty->getAs<RecordType>()) {
1026    const RecordDecl *D = RT->getDecl();
1027    if (!D->getDefinition())
1028      return false;
1029  }
1030
1031  return true;
1032}
1033
1034RegionRawOffset ElementRegion::getAsArrayOffset() const {
1035  CharUnits offset = CharUnits::Zero();
1036  const ElementRegion *ER = this;
1037  const MemRegion *superR = NULL;
1038  ASTContext &C = getContext();
1039
1040  // FIXME: Handle multi-dimensional arrays.
1041
1042  while (ER) {
1043    superR = ER->getSuperRegion();
1044
1045    // FIXME: generalize to symbolic offsets.
1046    SVal index = ER->getIndex();
1047    if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
1048      // Update the offset.
1049      int64_t i = CI->getValue().getSExtValue();
1050
1051      if (i != 0) {
1052        QualType elemType = ER->getElementType();
1053
1054        // If we are pointing to an incomplete type, go no further.
1055        if (!IsCompleteType(C, elemType)) {
1056          superR = ER;
1057          break;
1058        }
1059
1060        CharUnits size = C.getTypeSizeInChars(elemType);
1061        offset += (i * size);
1062      }
1063
1064      // Go to the next ElementRegion (if any).
1065      ER = dyn_cast<ElementRegion>(superR);
1066      continue;
1067    }
1068
1069    return NULL;
1070  }
1071
1072  assert(superR && "super region cannot be NULL");
1073  return RegionRawOffset(superR, offset);
1074}
1075
1076RegionOffset MemRegion::getAsOffset() const {
1077  const MemRegion *R = this;
1078  const MemRegion *SymbolicOffsetBase = 0;
1079  int64_t Offset = 0;
1080
1081  while (1) {
1082    switch (R->getKind()) {
1083    default:
1084      return RegionOffset(R, RegionOffset::Symbolic);
1085
1086    case SymbolicRegionKind:
1087    case AllocaRegionKind:
1088    case CompoundLiteralRegionKind:
1089    case CXXThisRegionKind:
1090    case StringRegionKind:
1091    case VarRegionKind:
1092    case CXXTempObjectRegionKind:
1093      goto Finish;
1094
1095    case ObjCIvarRegionKind:
1096      // This is a little strange, but it's a compromise between
1097      // ObjCIvarRegions having unknown compile-time offsets (when using the
1098      // non-fragile runtime) and yet still being distinct, non-overlapping
1099      // regions. Thus we treat them as "like" base regions for the purposes
1100      // of computing offsets.
1101      goto Finish;
1102
1103    case CXXBaseObjectRegionKind: {
1104      const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
1105      R = BOR->getSuperRegion();
1106
1107      QualType Ty;
1108      if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
1109        Ty = TVR->getDesugaredValueType(getContext());
1110      } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1111        // If our base region is symbolic, we don't know what type it really is.
1112        // Pretend the type of the symbol is the true dynamic type.
1113        // (This will at least be self-consistent for the life of the symbol.)
1114        Ty = SR->getSymbol()->getType()->getPointeeType();
1115      }
1116
1117      const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1118      if (!Child) {
1119        // We cannot compute the offset of the base class.
1120        SymbolicOffsetBase = R;
1121      }
1122
1123      // Don't bother calculating precise offsets if we already have a
1124      // symbolic offset somewhere in the chain.
1125      if (SymbolicOffsetBase)
1126        continue;
1127
1128      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
1129
1130      CharUnits BaseOffset;
1131      const CXXRecordDecl *Base = BOR->getDecl();
1132      if (Child->isVirtuallyDerivedFrom(Base))
1133        BaseOffset = Layout.getVBaseClassOffset(Base);
1134      else
1135        BaseOffset = Layout.getBaseClassOffset(Base);
1136
1137      // The base offset is in chars, not in bits.
1138      Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
1139      break;
1140    }
1141    case ElementRegionKind: {
1142      const ElementRegion *ER = cast<ElementRegion>(R);
1143      R = ER->getSuperRegion();
1144
1145      QualType EleTy = ER->getValueType();
1146      if (!IsCompleteType(getContext(), EleTy)) {
1147        // We cannot compute the offset of the base class.
1148        SymbolicOffsetBase = R;
1149        continue;
1150      }
1151
1152      SVal Index = ER->getIndex();
1153      if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
1154        // Don't bother calculating precise offsets if we already have a
1155        // symbolic offset somewhere in the chain.
1156        if (SymbolicOffsetBase)
1157          continue;
1158
1159        int64_t i = CI->getValue().getSExtValue();
1160        // This type size is in bits.
1161        Offset += i * getContext().getTypeSize(EleTy);
1162      } else {
1163        // We cannot compute offset for non-concrete index.
1164        SymbolicOffsetBase = R;
1165      }
1166      break;
1167    }
1168    case FieldRegionKind: {
1169      const FieldRegion *FR = cast<FieldRegion>(R);
1170      R = FR->getSuperRegion();
1171
1172      const RecordDecl *RD = FR->getDecl()->getParent();
1173      if (RD->isUnion() || !RD->isCompleteDefinition()) {
1174        // We cannot compute offset for incomplete type.
1175        // For unions, we could treat everything as offset 0, but we'd rather
1176        // treat each field as a symbolic offset so they aren't stored on top
1177        // of each other, since we depend on things in typed regions actually
1178        // matching their types.
1179        SymbolicOffsetBase = R;
1180      }
1181
1182      // Don't bother calculating precise offsets if we already have a
1183      // symbolic offset somewhere in the chain.
1184      if (SymbolicOffsetBase)
1185        continue;
1186
1187      // Get the field number.
1188      unsigned idx = 0;
1189      for (RecordDecl::field_iterator FI = RD->field_begin(),
1190             FE = RD->field_end(); FI != FE; ++FI, ++idx)
1191        if (FR->getDecl() == *FI)
1192          break;
1193
1194      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1195      // This is offset in bits.
1196      Offset += Layout.getFieldOffset(idx);
1197      break;
1198    }
1199    }
1200  }
1201
1202 Finish:
1203  if (SymbolicOffsetBase)
1204    return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1205  return RegionOffset(R, Offset);
1206}
1207
1208//===----------------------------------------------------------------------===//
1209// BlockDataRegion
1210//===----------------------------------------------------------------------===//
1211
1212std::pair<const VarRegion *, const VarRegion *>
1213BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1214  MemRegionManager &MemMgr = *getMemRegionManager();
1215  const VarRegion *VR = 0;
1216  const VarRegion *OriginalVR = 0;
1217
1218  if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1219    VR = MemMgr.getVarRegion(VD, this);
1220    OriginalVR = MemMgr.getVarRegion(VD, LC);
1221  }
1222  else {
1223    if (LC) {
1224      VR = MemMgr.getVarRegion(VD, LC);
1225      OriginalVR = VR;
1226    }
1227    else {
1228      VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
1229      OriginalVR = MemMgr.getVarRegion(VD, LC);
1230    }
1231  }
1232  return std::make_pair(VR, OriginalVR);
1233}
1234
1235void BlockDataRegion::LazyInitializeReferencedVars() {
1236  if (ReferencedVars)
1237    return;
1238
1239  AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
1240  AnalysisDeclContext::referenced_decls_iterator I, E;
1241  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
1242
1243  if (I == E) {
1244    ReferencedVars = (void*) 0x1;
1245    return;
1246  }
1247
1248  MemRegionManager &MemMgr = *getMemRegionManager();
1249  llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1250  BumpVectorContext BC(A);
1251
1252  typedef BumpVector<const MemRegion*> VarVec;
1253  VarVec *BV = (VarVec*) A.Allocate<VarVec>();
1254  new (BV) VarVec(BC, E - I);
1255  VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
1256  new (BVOriginal) VarVec(BC, E - I);
1257
1258  for ( ; I != E; ++I) {
1259    const VarRegion *VR = 0;
1260    const VarRegion *OriginalVR = 0;
1261    llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
1262    assert(VR);
1263    assert(OriginalVR);
1264    BV->push_back(VR, BC);
1265    BVOriginal->push_back(OriginalVR, BC);
1266  }
1267
1268  ReferencedVars = BV;
1269  OriginalVars = BVOriginal;
1270}
1271
1272BlockDataRegion::referenced_vars_iterator
1273BlockDataRegion::referenced_vars_begin() const {
1274  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1275
1276  BumpVector<const MemRegion*> *Vec =
1277    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1278
1279  if (Vec == (void*) 0x1)
1280    return BlockDataRegion::referenced_vars_iterator(0, 0);
1281
1282  BumpVector<const MemRegion*> *VecOriginal =
1283    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1284
1285  return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
1286                                                   VecOriginal->begin());
1287}
1288
1289BlockDataRegion::referenced_vars_iterator
1290BlockDataRegion::referenced_vars_end() const {
1291  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1292
1293  BumpVector<const MemRegion*> *Vec =
1294    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1295
1296  if (Vec == (void*) 0x1)
1297    return BlockDataRegion::referenced_vars_iterator(0, 0);
1298
1299  BumpVector<const MemRegion*> *VecOriginal =
1300    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1301
1302  return BlockDataRegion::referenced_vars_iterator(Vec->end(),
1303                                                   VecOriginal->end());
1304}
1305