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