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