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