MemRegion.cpp revision dc84cd5efdd3430efb22546b4ac656aa0540b210
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 (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) { 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 case GenericMemSpaceRegionKind: 1084 case StackLocalsSpaceRegionKind: 1085 case StackArgumentsSpaceRegionKind: 1086 case HeapSpaceRegionKind: 1087 case UnknownSpaceRegionKind: 1088 case StaticGlobalSpaceRegionKind: 1089 case GlobalInternalSpaceRegionKind: 1090 case GlobalSystemSpaceRegionKind: 1091 case GlobalImmutableSpaceRegionKind: 1092 // Stores can bind directly to a region space to set a default value. 1093 assert(Offset == 0 && !SymbolicOffsetBase); 1094 goto Finish; 1095 1096 case FunctionTextRegionKind: 1097 case BlockTextRegionKind: 1098 case BlockDataRegionKind: 1099 // These will never have bindings, but may end up having values requested 1100 // if the user does some strange casting. 1101 if (Offset != 0) 1102 SymbolicOffsetBase = R; 1103 goto Finish; 1104 1105 case SymbolicRegionKind: 1106 case AllocaRegionKind: 1107 case CompoundLiteralRegionKind: 1108 case CXXThisRegionKind: 1109 case StringRegionKind: 1110 case ObjCStringRegionKind: 1111 case VarRegionKind: 1112 case CXXTempObjectRegionKind: 1113 // Usual base regions. 1114 goto Finish; 1115 1116 case ObjCIvarRegionKind: 1117 // This is a little strange, but it's a compromise between 1118 // ObjCIvarRegions having unknown compile-time offsets (when using the 1119 // non-fragile runtime) and yet still being distinct, non-overlapping 1120 // regions. Thus we treat them as "like" base regions for the purposes 1121 // of computing offsets. 1122 goto Finish; 1123 1124 case CXXBaseObjectRegionKind: { 1125 const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R); 1126 R = BOR->getSuperRegion(); 1127 1128 QualType Ty; 1129 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) { 1130 Ty = TVR->getDesugaredValueType(getContext()); 1131 } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 1132 // If our base region is symbolic, we don't know what type it really is. 1133 // Pretend the type of the symbol is the true dynamic type. 1134 // (This will at least be self-consistent for the life of the symbol.) 1135 Ty = SR->getSymbol()->getType()->getPointeeType(); 1136 } 1137 1138 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 1139 if (!Child) { 1140 // We cannot compute the offset of the base class. 1141 SymbolicOffsetBase = R; 1142 } 1143 1144 // Don't bother calculating precise offsets if we already have a 1145 // symbolic offset somewhere in the chain. 1146 if (SymbolicOffsetBase) 1147 continue; 1148 1149 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child); 1150 1151 CharUnits BaseOffset; 1152 const CXXRecordDecl *Base = BOR->getDecl(); 1153 if (Child->isVirtuallyDerivedFrom(Base)) 1154 BaseOffset = Layout.getVBaseClassOffset(Base); 1155 else 1156 BaseOffset = Layout.getBaseClassOffset(Base); 1157 1158 // The base offset is in chars, not in bits. 1159 Offset += BaseOffset.getQuantity() * getContext().getCharWidth(); 1160 break; 1161 } 1162 case ElementRegionKind: { 1163 const ElementRegion *ER = cast<ElementRegion>(R); 1164 R = ER->getSuperRegion(); 1165 1166 QualType EleTy = ER->getValueType(); 1167 if (!IsCompleteType(getContext(), EleTy)) { 1168 // We cannot compute the offset of the base class. 1169 SymbolicOffsetBase = R; 1170 continue; 1171 } 1172 1173 SVal Index = ER->getIndex(); 1174 if (Optional<nonloc::ConcreteInt> CI = 1175 Index.getAs<nonloc::ConcreteInt>()) { 1176 // Don't bother calculating precise offsets if we already have a 1177 // symbolic offset somewhere in the chain. 1178 if (SymbolicOffsetBase) 1179 continue; 1180 1181 int64_t i = CI->getValue().getSExtValue(); 1182 // This type size is in bits. 1183 Offset += i * getContext().getTypeSize(EleTy); 1184 } else { 1185 // We cannot compute offset for non-concrete index. 1186 SymbolicOffsetBase = R; 1187 } 1188 break; 1189 } 1190 case FieldRegionKind: { 1191 const FieldRegion *FR = cast<FieldRegion>(R); 1192 R = FR->getSuperRegion(); 1193 1194 const RecordDecl *RD = FR->getDecl()->getParent(); 1195 if (RD->isUnion() || !RD->isCompleteDefinition()) { 1196 // We cannot compute offset for incomplete type. 1197 // For unions, we could treat everything as offset 0, but we'd rather 1198 // treat each field as a symbolic offset so they aren't stored on top 1199 // of each other, since we depend on things in typed regions actually 1200 // matching their types. 1201 SymbolicOffsetBase = R; 1202 } 1203 1204 // Don't bother calculating precise offsets if we already have a 1205 // symbolic offset somewhere in the chain. 1206 if (SymbolicOffsetBase) 1207 continue; 1208 1209 // Get the field number. 1210 unsigned idx = 0; 1211 for (RecordDecl::field_iterator FI = RD->field_begin(), 1212 FE = RD->field_end(); FI != FE; ++FI, ++idx) 1213 if (FR->getDecl() == *FI) 1214 break; 1215 1216 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1217 // This is offset in bits. 1218 Offset += Layout.getFieldOffset(idx); 1219 break; 1220 } 1221 } 1222 } 1223 1224 Finish: 1225 if (SymbolicOffsetBase) 1226 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 1227 return RegionOffset(R, Offset); 1228} 1229 1230//===----------------------------------------------------------------------===// 1231// BlockDataRegion 1232//===----------------------------------------------------------------------===// 1233 1234std::pair<const VarRegion *, const VarRegion *> 1235BlockDataRegion::getCaptureRegions(const VarDecl *VD) { 1236 MemRegionManager &MemMgr = *getMemRegionManager(); 1237 const VarRegion *VR = 0; 1238 const VarRegion *OriginalVR = 0; 1239 1240 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) { 1241 VR = MemMgr.getVarRegion(VD, this); 1242 OriginalVR = MemMgr.getVarRegion(VD, LC); 1243 } 1244 else { 1245 if (LC) { 1246 VR = MemMgr.getVarRegion(VD, LC); 1247 OriginalVR = VR; 1248 } 1249 else { 1250 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 1251 OriginalVR = MemMgr.getVarRegion(VD, LC); 1252 } 1253 } 1254 return std::make_pair(VR, OriginalVR); 1255} 1256 1257void BlockDataRegion::LazyInitializeReferencedVars() { 1258 if (ReferencedVars) 1259 return; 1260 1261 AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 1262 AnalysisDeclContext::referenced_decls_iterator I, E; 1263 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); 1264 1265 if (I == E) { 1266 ReferencedVars = (void*) 0x1; 1267 return; 1268 } 1269 1270 MemRegionManager &MemMgr = *getMemRegionManager(); 1271 llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 1272 BumpVectorContext BC(A); 1273 1274 typedef BumpVector<const MemRegion*> VarVec; 1275 VarVec *BV = (VarVec*) A.Allocate<VarVec>(); 1276 new (BV) VarVec(BC, E - I); 1277 VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>(); 1278 new (BVOriginal) VarVec(BC, E - I); 1279 1280 for ( ; I != E; ++I) { 1281 const VarRegion *VR = 0; 1282 const VarRegion *OriginalVR = 0; 1283 llvm::tie(VR, OriginalVR) = getCaptureRegions(*I); 1284 assert(VR); 1285 assert(OriginalVR); 1286 BV->push_back(VR, BC); 1287 BVOriginal->push_back(OriginalVR, BC); 1288 } 1289 1290 ReferencedVars = BV; 1291 OriginalVars = BVOriginal; 1292} 1293 1294BlockDataRegion::referenced_vars_iterator 1295BlockDataRegion::referenced_vars_begin() const { 1296 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1297 1298 BumpVector<const MemRegion*> *Vec = 1299 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1300 1301 if (Vec == (void*) 0x1) 1302 return BlockDataRegion::referenced_vars_iterator(0, 0); 1303 1304 BumpVector<const MemRegion*> *VecOriginal = 1305 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1306 1307 return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 1308 VecOriginal->begin()); 1309} 1310 1311BlockDataRegion::referenced_vars_iterator 1312BlockDataRegion::referenced_vars_end() const { 1313 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1314 1315 BumpVector<const MemRegion*> *Vec = 1316 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1317 1318 if (Vec == (void*) 0x1) 1319 return BlockDataRegion::referenced_vars_iterator(0, 0); 1320 1321 BumpVector<const MemRegion*> *VecOriginal = 1322 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1323 1324 return BlockDataRegion::referenced_vars_iterator(Vec->end(), 1325 VecOriginal->end()); 1326} 1327 1328const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 1329 for (referenced_vars_iterator I = referenced_vars_begin(), 1330 E = referenced_vars_end(); 1331 I != E; ++I) { 1332 if (I.getCapturedRegion() == R) 1333 return I.getOriginalRegion(); 1334 } 1335 return 0; 1336} 1337