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