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 (T->isIncompleteType()) 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 canPrintPrettyAsExpr(); 559 } 560 561 bool MemRegion::canPrintPrettyAsExpr() const { 562 return false; 563 } 564 565 void MemRegion::printPretty(raw_ostream &os) const { 566 assert(canPrintPretty() && "This region cannot be printed pretty."); 567 os << "'"; 568 printPrettyAsExpr(os); 569 os << "'"; 570 return; 571 } 572 573 void MemRegion::printPrettyAsExpr(raw_ostream &os) const { 574 llvm_unreachable("This region cannot be printed pretty."); 575 return; 576 } 577 578 bool VarRegion::canPrintPrettyAsExpr() const { 579 return true; 580 } 581 582 void VarRegion::printPrettyAsExpr(raw_ostream &os) const { 583 os << getDecl()->getName(); 584 } 585 586 bool ObjCIvarRegion::canPrintPrettyAsExpr() const { 587 return true; 588 } 589 590 void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const { 591 os << getDecl()->getName(); 592 } 593 594 bool FieldRegion::canPrintPretty() const { 595 return true; 596 } 597 598 bool FieldRegion::canPrintPrettyAsExpr() const { 599 return superRegion->canPrintPrettyAsExpr(); 600 } 601 602 void FieldRegion::printPrettyAsExpr(raw_ostream &os) const { 603 assert(canPrintPrettyAsExpr()); 604 superRegion->printPrettyAsExpr(os); 605 os << "." << getDecl()->getName(); 606 } 607 608 void FieldRegion::printPretty(raw_ostream &os) const { 609 if (canPrintPrettyAsExpr()) { 610 os << "\'"; 611 printPrettyAsExpr(os); 612 os << "'"; 613 } else { 614 os << "field " << "\'" << getDecl()->getName() << "'"; 615 } 616 return; 617 } 618 619 bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const { 620 return superRegion->canPrintPrettyAsExpr(); 621 } 622 623 void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const { 624 superRegion->printPrettyAsExpr(os); 625 } 626 627 //===----------------------------------------------------------------------===// 628 // MemRegionManager methods. 629 //===----------------------------------------------------------------------===// 630 631 template <typename REG> 632 const REG *MemRegionManager::LazyAllocate(REG*& region) { 633 if (!region) { 634 region = (REG*) A.Allocate<REG>(); 635 new (region) REG(this); 636 } 637 638 return region; 639 } 640 641 template <typename REG, typename ARG> 642 const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { 643 if (!region) { 644 region = (REG*) A.Allocate<REG>(); 645 new (region) REG(this, a); 646 } 647 648 return region; 649 } 650 651 const StackLocalsSpaceRegion* 652 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { 653 assert(STC); 654 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC]; 655 656 if (R) 657 return R; 658 659 R = A.Allocate<StackLocalsSpaceRegion>(); 660 new (R) StackLocalsSpaceRegion(this, STC); 661 return R; 662 } 663 664 const StackArgumentsSpaceRegion * 665 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { 666 assert(STC); 667 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC]; 668 669 if (R) 670 return R; 671 672 R = A.Allocate<StackArgumentsSpaceRegion>(); 673 new (R) StackArgumentsSpaceRegion(this, STC); 674 return R; 675 } 676 677 const GlobalsSpaceRegion 678 *MemRegionManager::getGlobalsRegion(MemRegion::Kind K, 679 const CodeTextRegion *CR) { 680 if (!CR) { 681 if (K == MemRegion::GlobalSystemSpaceRegionKind) 682 return LazyAllocate(SystemGlobals); 683 if (K == MemRegion::GlobalImmutableSpaceRegionKind) 684 return LazyAllocate(ImmutableGlobals); 685 assert(K == MemRegion::GlobalInternalSpaceRegionKind); 686 return LazyAllocate(InternalGlobals); 687 } 688 689 assert(K == MemRegion::StaticGlobalSpaceRegionKind); 690 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; 691 if (R) 692 return R; 693 694 R = A.Allocate<StaticGlobalSpaceRegion>(); 695 new (R) StaticGlobalSpaceRegion(this, CR); 696 return R; 697 } 698 699 const HeapSpaceRegion *MemRegionManager::getHeapRegion() { 700 return LazyAllocate(heap); 701 } 702 703 const MemSpaceRegion *MemRegionManager::getUnknownRegion() { 704 return LazyAllocate(unknown); 705 } 706 707 const MemSpaceRegion *MemRegionManager::getCodeRegion() { 708 return LazyAllocate(code); 709 } 710 711 //===----------------------------------------------------------------------===// 712 // Constructing regions. 713 //===----------------------------------------------------------------------===// 714 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){ 715 return getSubRegion<StringRegion>(Str, getGlobalsRegion()); 716 } 717 718 const ObjCStringRegion * 719 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){ 720 return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion()); 721 } 722 723 /// Look through a chain of LocationContexts to either find the 724 /// StackFrameContext that matches a DeclContext, or find a VarRegion 725 /// for a variable captured by a block. 726 static llvm::PointerUnion<const StackFrameContext *, const VarRegion *> 727 getStackOrCaptureRegionForDeclContext(const LocationContext *LC, 728 const DeclContext *DC, 729 const VarDecl *VD) { 730 while (LC) { 731 if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) { 732 if (cast<DeclContext>(SFC->getDecl()) == DC) 733 return SFC; 734 } 735 if (const BlockInvocationContext *BC = 736 dyn_cast<BlockInvocationContext>(LC)) { 737 const BlockDataRegion *BR = 738 static_cast<const BlockDataRegion*>(BC->getContextData()); 739 // FIXME: This can be made more efficient. 740 for (BlockDataRegion::referenced_vars_iterator 741 I = BR->referenced_vars_begin(), 742 E = BR->referenced_vars_end(); I != E; ++I) { 743 if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion())) 744 if (VR->getDecl() == VD) 745 return cast<VarRegion>(I.getCapturedRegion()); 746 } 747 } 748 749 LC = LC->getParent(); 750 } 751 return (const StackFrameContext*)0; 752 } 753 754 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, 755 const LocationContext *LC) { 756 const MemRegion *sReg = 0; 757 758 if (D->hasGlobalStorage() && !D->isStaticLocal()) { 759 760 // First handle the globals defined in system headers. 761 if (C.getSourceManager().isInSystemHeader(D->getLocation())) { 762 // Whitelist the system globals which often DO GET modified, assume the 763 // rest are immutable. 764 if (D->getName().find("errno") != StringRef::npos) 765 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); 766 else 767 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 768 769 // Treat other globals as GlobalInternal unless they are constants. 770 } else { 771 QualType GQT = D->getType(); 772 const Type *GT = GQT.getTypePtrOrNull(); 773 // TODO: We could walk the complex types here and see if everything is 774 // constified. 775 if (GT && GQT.isConstQualified() && GT->isArithmeticType()) 776 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 777 else 778 sReg = getGlobalsRegion(); 779 } 780 781 // Finally handle static locals. 782 } else { 783 // FIXME: Once we implement scope handling, we will need to properly lookup 784 // 'D' to the proper LocationContext. 785 const DeclContext *DC = D->getDeclContext(); 786 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V = 787 getStackOrCaptureRegionForDeclContext(LC, DC, D); 788 789 if (V.is<const VarRegion*>()) 790 return V.get<const VarRegion*>(); 791 792 const StackFrameContext *STC = V.get<const StackFrameContext*>(); 793 794 if (!STC) 795 sReg = getUnknownRegion(); 796 else { 797 if (D->hasLocalStorage()) { 798 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) 799 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) 800 : static_cast<const MemRegion*>(getStackLocalsRegion(STC)); 801 } 802 else { 803 assert(D->isStaticLocal()); 804 const Decl *STCD = STC->getDecl(); 805 if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD)) 806 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 807 getFunctionTextRegion(cast<NamedDecl>(STCD))); 808 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { 809 // FIXME: The fallback type here is totally bogus -- though it should 810 // never be queried, it will prevent uniquing with the real 811 // BlockTextRegion. Ideally we'd fix the AST so that we always had a 812 // signature. 813 QualType T; 814 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) 815 T = TSI->getType(); 816 else 817 T = getContext().getFunctionNoProtoType(getContext().VoidTy); 818 819 const BlockTextRegion *BTR = 820 getBlockTextRegion(BD, C.getCanonicalType(T), 821 STC->getAnalysisDeclContext()); 822 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 823 BTR); 824 } 825 else { 826 sReg = getGlobalsRegion(); 827 } 828 } 829 } 830 } 831 832 return getSubRegion<VarRegion>(D, sReg); 833 } 834 835 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, 836 const MemRegion *superR) { 837 return getSubRegion<VarRegion>(D, superR); 838 } 839 840 const BlockDataRegion * 841 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, 842 const LocationContext *LC) { 843 const MemRegion *sReg = 0; 844 const BlockDecl *BD = BC->getDecl(); 845 if (!BD->hasCaptures()) { 846 // This handles 'static' blocks. 847 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 848 } 849 else { 850 if (LC) { 851 // FIXME: Once we implement scope handling, we want the parent region 852 // to be the scope. 853 const StackFrameContext *STC = LC->getCurrentStackFrame(); 854 assert(STC); 855 sReg = getStackLocalsRegion(STC); 856 } 857 else { 858 // We allow 'LC' to be NULL for cases where want BlockDataRegions 859 // without context-sensitivity. 860 sReg = getUnknownRegion(); 861 } 862 } 863 864 return getSubRegion<BlockDataRegion>(BC, LC, sReg); 865 } 866 867 const CompoundLiteralRegion* 868 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 869 const LocationContext *LC) { 870 871 const MemRegion *sReg = 0; 872 873 if (CL->isFileScope()) 874 sReg = getGlobalsRegion(); 875 else { 876 const StackFrameContext *STC = LC->getCurrentStackFrame(); 877 assert(STC); 878 sReg = getStackLocalsRegion(STC); 879 } 880 881 return getSubRegion<CompoundLiteralRegion>(CL, sReg); 882 } 883 884 const ElementRegion* 885 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, 886 const MemRegion* superRegion, 887 ASTContext &Ctx){ 888 889 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 890 891 llvm::FoldingSetNodeID ID; 892 ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 893 894 void *InsertPos; 895 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); 896 ElementRegion* R = cast_or_null<ElementRegion>(data); 897 898 if (!R) { 899 R = (ElementRegion*) A.Allocate<ElementRegion>(); 900 new (R) ElementRegion(T, Idx, superRegion); 901 Regions.InsertNode(R, InsertPos); 902 } 903 904 return R; 905 } 906 907 const FunctionTextRegion * 908 MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) { 909 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); 910 } 911 912 const BlockTextRegion * 913 MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, 914 AnalysisDeclContext *AC) { 915 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion()); 916 } 917 918 919 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 920 const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { 921 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); 922 } 923 924 const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { 925 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); 926 } 927 928 const FieldRegion* 929 MemRegionManager::getFieldRegion(const FieldDecl *d, 930 const MemRegion* superRegion){ 931 return getSubRegion<FieldRegion>(d, superRegion); 932 } 933 934 const ObjCIvarRegion* 935 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d, 936 const MemRegion* superRegion) { 937 return getSubRegion<ObjCIvarRegion>(d, superRegion); 938 } 939 940 const CXXTempObjectRegion* 941 MemRegionManager::getCXXTempObjectRegion(Expr const *E, 942 LocationContext const *LC) { 943 const StackFrameContext *SFC = LC->getCurrentStackFrame(); 944 assert(SFC); 945 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC)); 946 } 947 948 /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base 949 /// class of the type of \p Super. 950 static bool isValidBaseClass(const CXXRecordDecl *BaseClass, 951 const TypedValueRegion *Super, 952 bool IsVirtual) { 953 BaseClass = BaseClass->getCanonicalDecl(); 954 955 const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl(); 956 if (!Class) 957 return true; 958 959 if (IsVirtual) 960 return Class->isVirtuallyDerivedFrom(BaseClass); 961 962 for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 963 E = Class->bases_end(); 964 I != E; ++I) { 965 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass) 966 return true; 967 } 968 969 return false; 970 } 971 972 const CXXBaseObjectRegion * 973 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD, 974 const MemRegion *Super, 975 bool IsVirtual) { 976 if (isa<TypedValueRegion>(Super)) { 977 assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual)); 978 (void)isValidBaseClass; 979 980 if (IsVirtual) { 981 // Virtual base regions should not be layered, since the layout rules 982 // are different. 983 while (const CXXBaseObjectRegion *Base = 984 dyn_cast<CXXBaseObjectRegion>(Super)) { 985 Super = Base->getSuperRegion(); 986 } 987 assert(Super && !isa<MemSpaceRegion>(Super)); 988 } 989 } 990 991 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super); 992 } 993 994 const CXXThisRegion* 995 MemRegionManager::getCXXThisRegion(QualType thisPointerTy, 996 const LocationContext *LC) { 997 const StackFrameContext *STC = LC->getCurrentStackFrame(); 998 assert(STC); 999 const PointerType *PT = thisPointerTy->getAs<PointerType>(); 1000 assert(PT); 1001 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC)); 1002 } 1003 1004 const AllocaRegion* 1005 MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt, 1006 const LocationContext *LC) { 1007 const StackFrameContext *STC = LC->getCurrentStackFrame(); 1008 assert(STC); 1009 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC)); 1010 } 1011 1012 const MemSpaceRegion *MemRegion::getMemorySpace() const { 1013 const MemRegion *R = this; 1014 const SubRegion* SR = dyn_cast<SubRegion>(this); 1015 1016 while (SR) { 1017 R = SR->getSuperRegion(); 1018 SR = dyn_cast<SubRegion>(R); 1019 } 1020 1021 return dyn_cast<MemSpaceRegion>(R); 1022 } 1023 1024 bool MemRegion::hasStackStorage() const { 1025 return isa<StackSpaceRegion>(getMemorySpace()); 1026 } 1027 1028 bool MemRegion::hasStackNonParametersStorage() const { 1029 return isa<StackLocalsSpaceRegion>(getMemorySpace()); 1030 } 1031 1032 bool MemRegion::hasStackParametersStorage() const { 1033 return isa<StackArgumentsSpaceRegion>(getMemorySpace()); 1034 } 1035 1036 bool MemRegion::hasGlobalsOrParametersStorage() const { 1037 const MemSpaceRegion *MS = getMemorySpace(); 1038 return isa<StackArgumentsSpaceRegion>(MS) || 1039 isa<GlobalsSpaceRegion>(MS); 1040 } 1041 1042 // getBaseRegion strips away all elements and fields, and get the base region 1043 // of them. 1044 const MemRegion *MemRegion::getBaseRegion() const { 1045 const MemRegion *R = this; 1046 while (true) { 1047 switch (R->getKind()) { 1048 case MemRegion::ElementRegionKind: 1049 case MemRegion::FieldRegionKind: 1050 case MemRegion::ObjCIvarRegionKind: 1051 case MemRegion::CXXBaseObjectRegionKind: 1052 R = cast<SubRegion>(R)->getSuperRegion(); 1053 continue; 1054 default: 1055 break; 1056 } 1057 break; 1058 } 1059 return R; 1060 } 1061 1062 bool MemRegion::isSubRegionOf(const MemRegion *R) const { 1063 return false; 1064 } 1065 1066 //===----------------------------------------------------------------------===// 1067 // View handling. 1068 //===----------------------------------------------------------------------===// 1069 1070 const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const { 1071 const MemRegion *R = this; 1072 while (true) { 1073 switch (R->getKind()) { 1074 case ElementRegionKind: { 1075 const ElementRegion *ER = cast<ElementRegion>(R); 1076 if (!ER->getIndex().isZeroConstant()) 1077 return R; 1078 R = ER->getSuperRegion(); 1079 break; 1080 } 1081 case CXXBaseObjectRegionKind: 1082 if (!StripBaseCasts) 1083 return R; 1084 R = cast<CXXBaseObjectRegion>(R)->getSuperRegion(); 1085 break; 1086 default: 1087 return R; 1088 } 1089 } 1090 } 1091 1092 const SymbolicRegion *MemRegion::getSymbolicBase() const { 1093 const SubRegion *SubR = dyn_cast<SubRegion>(this); 1094 1095 while (SubR) { 1096 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) 1097 return SymR; 1098 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion()); 1099 } 1100 return 0; 1101 } 1102 1103 // FIXME: Merge with the implementation of the same method in Store.cpp 1104 static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { 1105 if (const RecordType *RT = Ty->getAs<RecordType>()) { 1106 const RecordDecl *D = RT->getDecl(); 1107 if (!D->getDefinition()) 1108 return false; 1109 } 1110 1111 return true; 1112 } 1113 1114 RegionRawOffset ElementRegion::getAsArrayOffset() const { 1115 CharUnits offset = CharUnits::Zero(); 1116 const ElementRegion *ER = this; 1117 const MemRegion *superR = NULL; 1118 ASTContext &C = getContext(); 1119 1120 // FIXME: Handle multi-dimensional arrays. 1121 1122 while (ER) { 1123 superR = ER->getSuperRegion(); 1124 1125 // FIXME: generalize to symbolic offsets. 1126 SVal index = ER->getIndex(); 1127 if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) { 1128 // Update the offset. 1129 int64_t i = CI->getValue().getSExtValue(); 1130 1131 if (i != 0) { 1132 QualType elemType = ER->getElementType(); 1133 1134 // If we are pointing to an incomplete type, go no further. 1135 if (!IsCompleteType(C, elemType)) { 1136 superR = ER; 1137 break; 1138 } 1139 1140 CharUnits size = C.getTypeSizeInChars(elemType); 1141 offset += (i * size); 1142 } 1143 1144 // Go to the next ElementRegion (if any). 1145 ER = dyn_cast<ElementRegion>(superR); 1146 continue; 1147 } 1148 1149 return NULL; 1150 } 1151 1152 assert(superR && "super region cannot be NULL"); 1153 return RegionRawOffset(superR, offset); 1154 } 1155 1156 1157 /// Returns true if \p Base is an immediate base class of \p Child 1158 static bool isImmediateBase(const CXXRecordDecl *Child, 1159 const CXXRecordDecl *Base) { 1160 // Note that we do NOT canonicalize the base class here, because 1161 // ASTRecordLayout doesn't either. If that leads us down the wrong path, 1162 // so be it; at least we won't crash. 1163 for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(), 1164 E = Child->bases_end(); 1165 I != E; ++I) { 1166 if (I->getType()->getAsCXXRecordDecl() == Base) 1167 return true; 1168 } 1169 1170 return false; 1171 } 1172 1173 RegionOffset MemRegion::getAsOffset() const { 1174 const MemRegion *R = this; 1175 const MemRegion *SymbolicOffsetBase = 0; 1176 int64_t Offset = 0; 1177 1178 while (1) { 1179 switch (R->getKind()) { 1180 case GenericMemSpaceRegionKind: 1181 case StackLocalsSpaceRegionKind: 1182 case StackArgumentsSpaceRegionKind: 1183 case HeapSpaceRegionKind: 1184 case UnknownSpaceRegionKind: 1185 case StaticGlobalSpaceRegionKind: 1186 case GlobalInternalSpaceRegionKind: 1187 case GlobalSystemSpaceRegionKind: 1188 case GlobalImmutableSpaceRegionKind: 1189 // Stores can bind directly to a region space to set a default value. 1190 assert(Offset == 0 && !SymbolicOffsetBase); 1191 goto Finish; 1192 1193 case FunctionTextRegionKind: 1194 case BlockTextRegionKind: 1195 case BlockDataRegionKind: 1196 // These will never have bindings, but may end up having values requested 1197 // if the user does some strange casting. 1198 if (Offset != 0) 1199 SymbolicOffsetBase = R; 1200 goto Finish; 1201 1202 case SymbolicRegionKind: 1203 case AllocaRegionKind: 1204 case CompoundLiteralRegionKind: 1205 case CXXThisRegionKind: 1206 case StringRegionKind: 1207 case ObjCStringRegionKind: 1208 case VarRegionKind: 1209 case CXXTempObjectRegionKind: 1210 // Usual base regions. 1211 goto Finish; 1212 1213 case ObjCIvarRegionKind: 1214 // This is a little strange, but it's a compromise between 1215 // ObjCIvarRegions having unknown compile-time offsets (when using the 1216 // non-fragile runtime) and yet still being distinct, non-overlapping 1217 // regions. Thus we treat them as "like" base regions for the purposes 1218 // of computing offsets. 1219 goto Finish; 1220 1221 case CXXBaseObjectRegionKind: { 1222 const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R); 1223 R = BOR->getSuperRegion(); 1224 1225 QualType Ty; 1226 bool RootIsSymbolic = false; 1227 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) { 1228 Ty = TVR->getDesugaredValueType(getContext()); 1229 } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 1230 // If our base region is symbolic, we don't know what type it really is. 1231 // Pretend the type of the symbol is the true dynamic type. 1232 // (This will at least be self-consistent for the life of the symbol.) 1233 Ty = SR->getSymbol()->getType()->getPointeeType(); 1234 RootIsSymbolic = true; 1235 } 1236 1237 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 1238 if (!Child) { 1239 // We cannot compute the offset of the base class. 1240 SymbolicOffsetBase = R; 1241 } 1242 1243 if (RootIsSymbolic) { 1244 // Base layers on symbolic regions may not be type-correct. 1245 // Double-check the inheritance here, and revert to a symbolic offset 1246 // if it's invalid (e.g. due to a reinterpret_cast). 1247 if (BOR->isVirtual()) { 1248 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) 1249 SymbolicOffsetBase = R; 1250 } else { 1251 if (!isImmediateBase(Child, BOR->getDecl())) 1252 SymbolicOffsetBase = R; 1253 } 1254 } 1255 1256 // Don't bother calculating precise offsets if we already have a 1257 // symbolic offset somewhere in the chain. 1258 if (SymbolicOffsetBase) 1259 continue; 1260 1261 CharUnits BaseOffset; 1262 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child); 1263 if (BOR->isVirtual()) 1264 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl()); 1265 else 1266 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl()); 1267 1268 // The base offset is in chars, not in bits. 1269 Offset += BaseOffset.getQuantity() * getContext().getCharWidth(); 1270 break; 1271 } 1272 case ElementRegionKind: { 1273 const ElementRegion *ER = cast<ElementRegion>(R); 1274 R = ER->getSuperRegion(); 1275 1276 QualType EleTy = ER->getValueType(); 1277 if (!IsCompleteType(getContext(), EleTy)) { 1278 // We cannot compute the offset of the base class. 1279 SymbolicOffsetBase = R; 1280 continue; 1281 } 1282 1283 SVal Index = ER->getIndex(); 1284 if (Optional<nonloc::ConcreteInt> CI = 1285 Index.getAs<nonloc::ConcreteInt>()) { 1286 // Don't bother calculating precise offsets if we already have a 1287 // symbolic offset somewhere in the chain. 1288 if (SymbolicOffsetBase) 1289 continue; 1290 1291 int64_t i = CI->getValue().getSExtValue(); 1292 // This type size is in bits. 1293 Offset += i * getContext().getTypeSize(EleTy); 1294 } else { 1295 // We cannot compute offset for non-concrete index. 1296 SymbolicOffsetBase = R; 1297 } 1298 break; 1299 } 1300 case FieldRegionKind: { 1301 const FieldRegion *FR = cast<FieldRegion>(R); 1302 R = FR->getSuperRegion(); 1303 1304 const RecordDecl *RD = FR->getDecl()->getParent(); 1305 if (RD->isUnion() || !RD->isCompleteDefinition()) { 1306 // We cannot compute offset for incomplete type. 1307 // For unions, we could treat everything as offset 0, but we'd rather 1308 // treat each field as a symbolic offset so they aren't stored on top 1309 // of each other, since we depend on things in typed regions actually 1310 // matching their types. 1311 SymbolicOffsetBase = R; 1312 } 1313 1314 // Don't bother calculating precise offsets if we already have a 1315 // symbolic offset somewhere in the chain. 1316 if (SymbolicOffsetBase) 1317 continue; 1318 1319 // Get the field number. 1320 unsigned idx = 0; 1321 for (RecordDecl::field_iterator FI = RD->field_begin(), 1322 FE = RD->field_end(); FI != FE; ++FI, ++idx) 1323 if (FR->getDecl() == *FI) 1324 break; 1325 1326 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1327 // This is offset in bits. 1328 Offset += Layout.getFieldOffset(idx); 1329 break; 1330 } 1331 } 1332 } 1333 1334 Finish: 1335 if (SymbolicOffsetBase) 1336 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 1337 return RegionOffset(R, Offset); 1338 } 1339 1340 //===----------------------------------------------------------------------===// 1341 // BlockDataRegion 1342 //===----------------------------------------------------------------------===// 1343 1344 std::pair<const VarRegion *, const VarRegion *> 1345 BlockDataRegion::getCaptureRegions(const VarDecl *VD) { 1346 MemRegionManager &MemMgr = *getMemRegionManager(); 1347 const VarRegion *VR = 0; 1348 const VarRegion *OriginalVR = 0; 1349 1350 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) { 1351 VR = MemMgr.getVarRegion(VD, this); 1352 OriginalVR = MemMgr.getVarRegion(VD, LC); 1353 } 1354 else { 1355 if (LC) { 1356 VR = MemMgr.getVarRegion(VD, LC); 1357 OriginalVR = VR; 1358 } 1359 else { 1360 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 1361 OriginalVR = MemMgr.getVarRegion(VD, LC); 1362 } 1363 } 1364 return std::make_pair(VR, OriginalVR); 1365 } 1366 1367 void BlockDataRegion::LazyInitializeReferencedVars() { 1368 if (ReferencedVars) 1369 return; 1370 1371 AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 1372 AnalysisDeclContext::referenced_decls_iterator I, E; 1373 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); 1374 1375 if (I == E) { 1376 ReferencedVars = (void*) 0x1; 1377 return; 1378 } 1379 1380 MemRegionManager &MemMgr = *getMemRegionManager(); 1381 llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 1382 BumpVectorContext BC(A); 1383 1384 typedef BumpVector<const MemRegion*> VarVec; 1385 VarVec *BV = (VarVec*) A.Allocate<VarVec>(); 1386 new (BV) VarVec(BC, E - I); 1387 VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>(); 1388 new (BVOriginal) VarVec(BC, E - I); 1389 1390 for ( ; I != E; ++I) { 1391 const VarRegion *VR = 0; 1392 const VarRegion *OriginalVR = 0; 1393 llvm::tie(VR, OriginalVR) = getCaptureRegions(*I); 1394 assert(VR); 1395 assert(OriginalVR); 1396 BV->push_back(VR, BC); 1397 BVOriginal->push_back(OriginalVR, BC); 1398 } 1399 1400 ReferencedVars = BV; 1401 OriginalVars = BVOriginal; 1402 } 1403 1404 BlockDataRegion::referenced_vars_iterator 1405 BlockDataRegion::referenced_vars_begin() const { 1406 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1407 1408 BumpVector<const MemRegion*> *Vec = 1409 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1410 1411 if (Vec == (void*) 0x1) 1412 return BlockDataRegion::referenced_vars_iterator(0, 0); 1413 1414 BumpVector<const MemRegion*> *VecOriginal = 1415 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1416 1417 return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 1418 VecOriginal->begin()); 1419 } 1420 1421 BlockDataRegion::referenced_vars_iterator 1422 BlockDataRegion::referenced_vars_end() const { 1423 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1424 1425 BumpVector<const MemRegion*> *Vec = 1426 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1427 1428 if (Vec == (void*) 0x1) 1429 return BlockDataRegion::referenced_vars_iterator(0, 0); 1430 1431 BumpVector<const MemRegion*> *VecOriginal = 1432 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1433 1434 return BlockDataRegion::referenced_vars_iterator(Vec->end(), 1435 VecOriginal->end()); 1436 } 1437 1438 const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 1439 for (referenced_vars_iterator I = referenced_vars_begin(), 1440 E = referenced_vars_end(); 1441 I != E; ++I) { 1442 if (I.getCapturedRegion() == R) 1443 return I.getOriginalRegion(); 1444 } 1445 return 0; 1446 } 1447