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