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