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