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