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 (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) { 793 const llvm::APInt &Size = CAT->getSize(); 794 if (Size.isZero()) 795 return true; 796 797 const AnalyzerOptions &Opts = SVB.getAnalyzerOptions(); 798 if (Opts.ShouldConsiderSingleElementArraysAsFlexibleArrayMembers && 799 Size.isOne()) 800 return true; 801 } 802 return false; 803 }; 804 805 if (isFlexibleArrayMemberCandidate(Ty)) 806 return UnknownVal(); 807 808 return Size; 809 } 810 // FIXME: The following are being used in 'SimpleSValBuilder' and in 811 // 'ArrayBoundChecker::checkLocation' because there is no symbol to 812 // represent the regions more appropriately. 813 case MemRegion::BlockDataRegionKind: 814 case MemRegion::BlockCodeRegionKind: 815 case MemRegion::FunctionCodeRegionKind: 816 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR)); 817 default: 818 llvm_unreachable("Unhandled region"); 819 } 820 } 821 822 template <typename REG> 823 const REG *MemRegionManager::LazyAllocate(REG*& region) { 824 if (!region) { 825 region = A.Allocate<REG>(); 826 new (region) REG(*this); 827 } 828 829 return region; 830 } 831 832 template <typename REG, typename ARG> 833 const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { 834 if (!region) { 835 region = A.Allocate<REG>(); 836 new (region) REG(this, a); 837 } 838 839 return region; 840 } 841 842 const StackLocalsSpaceRegion* 843 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { 844 assert(STC); 845 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC]; 846 847 if (R) 848 return R; 849 850 R = A.Allocate<StackLocalsSpaceRegion>(); 851 new (R) StackLocalsSpaceRegion(*this, STC); 852 return R; 853 } 854 855 const StackArgumentsSpaceRegion * 856 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { 857 assert(STC); 858 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC]; 859 860 if (R) 861 return R; 862 863 R = A.Allocate<StackArgumentsSpaceRegion>(); 864 new (R) StackArgumentsSpaceRegion(*this, STC); 865 return R; 866 } 867 868 const GlobalsSpaceRegion 869 *MemRegionManager::getGlobalsRegion(MemRegion::Kind K, 870 const CodeTextRegion *CR) { 871 if (!CR) { 872 if (K == MemRegion::GlobalSystemSpaceRegionKind) 873 return LazyAllocate(SystemGlobals); 874 if (K == MemRegion::GlobalImmutableSpaceRegionKind) 875 return LazyAllocate(ImmutableGlobals); 876 assert(K == MemRegion::GlobalInternalSpaceRegionKind); 877 return LazyAllocate(InternalGlobals); 878 } 879 880 assert(K == MemRegion::StaticGlobalSpaceRegionKind); 881 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; 882 if (R) 883 return R; 884 885 R = A.Allocate<StaticGlobalSpaceRegion>(); 886 new (R) StaticGlobalSpaceRegion(*this, CR); 887 return R; 888 } 889 890 const HeapSpaceRegion *MemRegionManager::getHeapRegion() { 891 return LazyAllocate(heap); 892 } 893 894 const UnknownSpaceRegion *MemRegionManager::getUnknownRegion() { 895 return LazyAllocate(unknown); 896 } 897 898 const CodeSpaceRegion *MemRegionManager::getCodeRegion() { 899 return LazyAllocate(code); 900 } 901 902 //===----------------------------------------------------------------------===// 903 // Constructing regions. 904 //===----------------------------------------------------------------------===// 905 906 const StringRegion *MemRegionManager::getStringRegion(const StringLiteral *Str){ 907 return getSubRegion<StringRegion>( 908 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion())); 909 } 910 911 const ObjCStringRegion * 912 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){ 913 return getSubRegion<ObjCStringRegion>( 914 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion())); 915 } 916 917 /// Look through a chain of LocationContexts to either find the 918 /// StackFrameContext that matches a DeclContext, or find a VarRegion 919 /// for a variable captured by a block. 920 static llvm::PointerUnion<const StackFrameContext *, const VarRegion *> 921 getStackOrCaptureRegionForDeclContext(const LocationContext *LC, 922 const DeclContext *DC, 923 const VarDecl *VD) { 924 while (LC) { 925 if (const auto *SFC = dyn_cast<StackFrameContext>(LC)) { 926 if (cast<DeclContext>(SFC->getDecl()) == DC) 927 return SFC; 928 } 929 if (const auto *BC = dyn_cast<BlockInvocationContext>(LC)) { 930 const auto *BR = static_cast<const BlockDataRegion *>(BC->getData()); 931 // FIXME: This can be made more efficient. 932 for (BlockDataRegion::referenced_vars_iterator 933 I = BR->referenced_vars_begin(), 934 E = BR->referenced_vars_end(); I != E; ++I) { 935 const TypedValueRegion *OrigR = I.getOriginalRegion(); 936 if (const auto *VR = dyn_cast<VarRegion>(OrigR)) { 937 if (VR->getDecl() == VD) 938 return cast<VarRegion>(I.getCapturedRegion()); 939 } 940 } 941 } 942 943 LC = LC->getParent(); 944 } 945 return (const StackFrameContext *)nullptr; 946 } 947 948 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, 949 const LocationContext *LC) { 950 const auto *PVD = dyn_cast<ParmVarDecl>(D); 951 if (PVD) { 952 unsigned Index = PVD->getFunctionScopeIndex(); 953 const StackFrameContext *SFC = LC->getStackFrame(); 954 const Stmt *CallSite = SFC->getCallSite(); 955 if (CallSite) { 956 const Decl *D = SFC->getDecl(); 957 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 958 if (Index < FD->param_size() && FD->parameters()[Index] == PVD) 959 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, 960 getStackArgumentsRegion(SFC)); 961 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) { 962 if (Index < BD->param_size() && BD->parameters()[Index] == PVD) 963 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, 964 getStackArgumentsRegion(SFC)); 965 } else { 966 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, 967 getStackArgumentsRegion(SFC)); 968 } 969 } 970 } 971 972 D = D->getCanonicalDecl(); 973 const MemRegion *sReg = nullptr; 974 975 if (D->hasGlobalStorage() && !D->isStaticLocal()) { 976 QualType Ty = D->getType(); 977 assert(!Ty.isNull()); 978 if (Ty.isConstQualified()) { 979 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 980 } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) { 981 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); 982 } else { 983 sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind); 984 } 985 986 // Finally handle static locals. 987 } else { 988 // FIXME: Once we implement scope handling, we will need to properly lookup 989 // 'D' to the proper LocationContext. 990 const DeclContext *DC = D->getDeclContext(); 991 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V = 992 getStackOrCaptureRegionForDeclContext(LC, DC, D); 993 994 if (V.is<const VarRegion*>()) 995 return V.get<const VarRegion*>(); 996 997 const auto *STC = V.get<const StackFrameContext *>(); 998 999 if (!STC) { 1000 // FIXME: Assign a more sensible memory space to static locals 1001 // we see from within blocks that we analyze as top-level declarations. 1002 sReg = getUnknownRegion(); 1003 } else { 1004 if (D->hasLocalStorage()) { 1005 sReg = 1006 isa<ParmVarDecl, ImplicitParamDecl>(D) 1007 ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC)) 1008 : static_cast<const MemRegion *>(getStackLocalsRegion(STC)); 1009 } 1010 else { 1011 assert(D->isStaticLocal()); 1012 const Decl *STCD = STC->getDecl(); 1013 if (isa<FunctionDecl, ObjCMethodDecl>(STCD)) 1014 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 1015 getFunctionCodeRegion(cast<NamedDecl>(STCD))); 1016 else if (const auto *BD = dyn_cast<BlockDecl>(STCD)) { 1017 // FIXME: The fallback type here is totally bogus -- though it should 1018 // never be queried, it will prevent uniquing with the real 1019 // BlockCodeRegion. Ideally we'd fix the AST so that we always had a 1020 // signature. 1021 QualType T; 1022 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) 1023 T = TSI->getType(); 1024 if (T.isNull()) 1025 T = getContext().VoidTy; 1026 if (!T->getAs<FunctionType>()) { 1027 FunctionProtoType::ExtProtoInfo Ext; 1028 T = getContext().getFunctionType(T, None, Ext); 1029 } 1030 T = getContext().getBlockPointerType(T); 1031 1032 const BlockCodeRegion *BTR = 1033 getBlockCodeRegion(BD, Ctx.getCanonicalType(T), 1034 STC->getAnalysisDeclContext()); 1035 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 1036 BTR); 1037 } 1038 else { 1039 sReg = getGlobalsRegion(); 1040 } 1041 } 1042 } 1043 } 1044 1045 return getSubRegion<NonParamVarRegion>(D, sReg); 1046 } 1047 1048 const NonParamVarRegion * 1049 MemRegionManager::getNonParamVarRegion(const VarDecl *D, 1050 const MemRegion *superR) { 1051 D = D->getCanonicalDecl(); 1052 return getSubRegion<NonParamVarRegion>(D, superR); 1053 } 1054 1055 const ParamVarRegion * 1056 MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index, 1057 const LocationContext *LC) { 1058 const StackFrameContext *SFC = LC->getStackFrame(); 1059 assert(SFC); 1060 return getSubRegion<ParamVarRegion>(OriginExpr, Index, 1061 getStackArgumentsRegion(SFC)); 1062 } 1063 1064 const BlockDataRegion * 1065 MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC, 1066 const LocationContext *LC, 1067 unsigned blockCount) { 1068 const MemSpaceRegion *sReg = nullptr; 1069 const BlockDecl *BD = BC->getDecl(); 1070 if (!BD->hasCaptures()) { 1071 // This handles 'static' blocks. 1072 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 1073 } 1074 else { 1075 if (LC) { 1076 // FIXME: Once we implement scope handling, we want the parent region 1077 // to be the scope. 1078 const StackFrameContext *STC = LC->getStackFrame(); 1079 assert(STC); 1080 sReg = getStackLocalsRegion(STC); 1081 } 1082 else { 1083 // We allow 'LC' to be NULL for cases where want BlockDataRegions 1084 // without context-sensitivity. 1085 sReg = getUnknownRegion(); 1086 } 1087 } 1088 1089 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg); 1090 } 1091 1092 const CXXTempObjectRegion * 1093 MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) { 1094 return getSubRegion<CXXTempObjectRegion>( 1095 Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr)); 1096 } 1097 1098 const CompoundLiteralRegion* 1099 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1100 const LocationContext *LC) { 1101 const MemSpaceRegion *sReg = nullptr; 1102 1103 if (CL->isFileScope()) 1104 sReg = getGlobalsRegion(); 1105 else { 1106 const StackFrameContext *STC = LC->getStackFrame(); 1107 assert(STC); 1108 sReg = getStackLocalsRegion(STC); 1109 } 1110 1111 return getSubRegion<CompoundLiteralRegion>(CL, sReg); 1112 } 1113 1114 const ElementRegion* 1115 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, 1116 const SubRegion* superRegion, 1117 ASTContext &Ctx){ 1118 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 1119 1120 llvm::FoldingSetNodeID ID; 1121 ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 1122 1123 void *InsertPos; 1124 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); 1125 auto *R = cast_or_null<ElementRegion>(data); 1126 1127 if (!R) { 1128 R = A.Allocate<ElementRegion>(); 1129 new (R) ElementRegion(T, Idx, superRegion); 1130 Regions.InsertNode(R, InsertPos); 1131 } 1132 1133 return R; 1134 } 1135 1136 const FunctionCodeRegion * 1137 MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) { 1138 // To think: should we canonicalize the declaration here? 1139 return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion()); 1140 } 1141 1142 const BlockCodeRegion * 1143 MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, 1144 AnalysisDeclContext *AC) { 1145 return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion()); 1146 } 1147 1148 const SymbolicRegion * 1149 MemRegionManager::getSymbolicRegion(SymbolRef sym, 1150 const MemSpaceRegion *MemSpace) { 1151 if (MemSpace == nullptr) 1152 MemSpace = getUnknownRegion(); 1153 return getSubRegion<SymbolicRegion>(sym, MemSpace); 1154 } 1155 1156 const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { 1157 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); 1158 } 1159 1160 const FieldRegion* 1161 MemRegionManager::getFieldRegion(const FieldDecl *d, 1162 const SubRegion* superRegion){ 1163 return getSubRegion<FieldRegion>(d, superRegion); 1164 } 1165 1166 const ObjCIvarRegion* 1167 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d, 1168 const SubRegion* superRegion) { 1169 return getSubRegion<ObjCIvarRegion>(d, superRegion); 1170 } 1171 1172 const CXXTempObjectRegion* 1173 MemRegionManager::getCXXTempObjectRegion(Expr const *E, 1174 LocationContext const *LC) { 1175 const StackFrameContext *SFC = LC->getStackFrame(); 1176 assert(SFC); 1177 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC)); 1178 } 1179 1180 /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base 1181 /// class of the type of \p Super. 1182 static bool isValidBaseClass(const CXXRecordDecl *BaseClass, 1183 const TypedValueRegion *Super, 1184 bool IsVirtual) { 1185 BaseClass = BaseClass->getCanonicalDecl(); 1186 1187 const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl(); 1188 if (!Class) 1189 return true; 1190 1191 if (IsVirtual) 1192 return Class->isVirtuallyDerivedFrom(BaseClass); 1193 1194 for (const auto &I : Class->bases()) { 1195 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass) 1196 return true; 1197 } 1198 1199 return false; 1200 } 1201 1202 const CXXBaseObjectRegion * 1203 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD, 1204 const SubRegion *Super, 1205 bool IsVirtual) { 1206 if (isa<TypedValueRegion>(Super)) { 1207 assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual)); 1208 (void)&isValidBaseClass; 1209 1210 if (IsVirtual) { 1211 // Virtual base regions should not be layered, since the layout rules 1212 // are different. 1213 while (const auto *Base = dyn_cast<CXXBaseObjectRegion>(Super)) 1214 Super = cast<SubRegion>(Base->getSuperRegion()); 1215 assert(Super && !isa<MemSpaceRegion>(Super)); 1216 } 1217 } 1218 1219 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super); 1220 } 1221 1222 const CXXDerivedObjectRegion * 1223 MemRegionManager::getCXXDerivedObjectRegion(const CXXRecordDecl *RD, 1224 const SubRegion *Super) { 1225 return getSubRegion<CXXDerivedObjectRegion>(RD, Super); 1226 } 1227 1228 const CXXThisRegion* 1229 MemRegionManager::getCXXThisRegion(QualType thisPointerTy, 1230 const LocationContext *LC) { 1231 const auto *PT = thisPointerTy->getAs<PointerType>(); 1232 assert(PT); 1233 // Inside the body of the operator() of a lambda a this expr might refer to an 1234 // object in one of the parent location contexts. 1235 const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl()); 1236 // FIXME: when operator() of lambda is analyzed as a top level function and 1237 // 'this' refers to a this to the enclosing scope, there is no right region to 1238 // return. 1239 while (!LC->inTopFrame() && (!D || D->isStatic() || 1240 PT != D->getThisType()->getAs<PointerType>())) { 1241 LC = LC->getParent(); 1242 D = dyn_cast<CXXMethodDecl>(LC->getDecl()); 1243 } 1244 const StackFrameContext *STC = LC->getStackFrame(); 1245 assert(STC); 1246 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC)); 1247 } 1248 1249 const AllocaRegion* 1250 MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt, 1251 const LocationContext *LC) { 1252 const StackFrameContext *STC = LC->getStackFrame(); 1253 assert(STC); 1254 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC)); 1255 } 1256 1257 const MemSpaceRegion *MemRegion::getMemorySpace() const { 1258 const MemRegion *R = this; 1259 const auto *SR = dyn_cast<SubRegion>(this); 1260 1261 while (SR) { 1262 R = SR->getSuperRegion(); 1263 SR = dyn_cast<SubRegion>(R); 1264 } 1265 1266 return dyn_cast<MemSpaceRegion>(R); 1267 } 1268 1269 bool MemRegion::hasStackStorage() const { 1270 return isa<StackSpaceRegion>(getMemorySpace()); 1271 } 1272 1273 bool MemRegion::hasStackNonParametersStorage() const { 1274 return isa<StackLocalsSpaceRegion>(getMemorySpace()); 1275 } 1276 1277 bool MemRegion::hasStackParametersStorage() const { 1278 return isa<StackArgumentsSpaceRegion>(getMemorySpace()); 1279 } 1280 1281 bool MemRegion::hasGlobalsOrParametersStorage() const { 1282 return isa<StackArgumentsSpaceRegion, GlobalsSpaceRegion>(getMemorySpace()); 1283 } 1284 1285 // getBaseRegion strips away all elements and fields, and get the base region 1286 // of them. 1287 const MemRegion *MemRegion::getBaseRegion() const { 1288 const MemRegion *R = this; 1289 while (true) { 1290 switch (R->getKind()) { 1291 case MemRegion::ElementRegionKind: 1292 case MemRegion::FieldRegionKind: 1293 case MemRegion::ObjCIvarRegionKind: 1294 case MemRegion::CXXBaseObjectRegionKind: 1295 case MemRegion::CXXDerivedObjectRegionKind: 1296 R = cast<SubRegion>(R)->getSuperRegion(); 1297 continue; 1298 default: 1299 break; 1300 } 1301 break; 1302 } 1303 return R; 1304 } 1305 1306 // getgetMostDerivedObjectRegion gets the region of the root class of a C++ 1307 // class hierarchy. 1308 const MemRegion *MemRegion::getMostDerivedObjectRegion() const { 1309 const MemRegion *R = this; 1310 while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R)) 1311 R = BR->getSuperRegion(); 1312 return R; 1313 } 1314 1315 bool MemRegion::isSubRegionOf(const MemRegion *) const { 1316 return false; 1317 } 1318 1319 //===----------------------------------------------------------------------===// 1320 // View handling. 1321 //===----------------------------------------------------------------------===// 1322 1323 const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const { 1324 const MemRegion *R = this; 1325 while (true) { 1326 switch (R->getKind()) { 1327 case ElementRegionKind: { 1328 const auto *ER = cast<ElementRegion>(R); 1329 if (!ER->getIndex().isZeroConstant()) 1330 return R; 1331 R = ER->getSuperRegion(); 1332 break; 1333 } 1334 case CXXBaseObjectRegionKind: 1335 case CXXDerivedObjectRegionKind: 1336 if (!StripBaseAndDerivedCasts) 1337 return R; 1338 R = cast<TypedValueRegion>(R)->getSuperRegion(); 1339 break; 1340 default: 1341 return R; 1342 } 1343 } 1344 } 1345 1346 const SymbolicRegion *MemRegion::getSymbolicBase() const { 1347 const auto *SubR = dyn_cast<SubRegion>(this); 1348 1349 while (SubR) { 1350 if (const auto *SymR = dyn_cast<SymbolicRegion>(SubR)) 1351 return SymR; 1352 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion()); 1353 } 1354 return nullptr; 1355 } 1356 1357 RegionRawOffset ElementRegion::getAsArrayOffset() const { 1358 int64_t offset = 0; 1359 const ElementRegion *ER = this; 1360 const MemRegion *superR = nullptr; 1361 ASTContext &C = getContext(); 1362 1363 // FIXME: Handle multi-dimensional arrays. 1364 1365 while (ER) { 1366 superR = ER->getSuperRegion(); 1367 1368 // FIXME: generalize to symbolic offsets. 1369 SVal index = ER->getIndex(); 1370 if (auto CI = index.getAs<nonloc::ConcreteInt>()) { 1371 // Update the offset. 1372 int64_t i = CI->getValue().getSExtValue(); 1373 1374 if (i != 0) { 1375 QualType elemType = ER->getElementType(); 1376 1377 // If we are pointing to an incomplete type, go no further. 1378 if (elemType->isIncompleteType()) { 1379 superR = ER; 1380 break; 1381 } 1382 1383 int64_t size = C.getTypeSizeInChars(elemType).getQuantity(); 1384 if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) { 1385 offset = *NewOffset; 1386 } else { 1387 LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: " 1388 << "offset overflowing, returning unknown\n"); 1389 1390 return nullptr; 1391 } 1392 } 1393 1394 // Go to the next ElementRegion (if any). 1395 ER = dyn_cast<ElementRegion>(superR); 1396 continue; 1397 } 1398 1399 return nullptr; 1400 } 1401 1402 assert(superR && "super region cannot be NULL"); 1403 return RegionRawOffset(superR, CharUnits::fromQuantity(offset)); 1404 } 1405 1406 /// Returns true if \p Base is an immediate base class of \p Child 1407 static bool isImmediateBase(const CXXRecordDecl *Child, 1408 const CXXRecordDecl *Base) { 1409 assert(Child && "Child must not be null"); 1410 // Note that we do NOT canonicalize the base class here, because 1411 // ASTRecordLayout doesn't either. If that leads us down the wrong path, 1412 // so be it; at least we won't crash. 1413 for (const auto &I : Child->bases()) { 1414 if (I.getType()->getAsCXXRecordDecl() == Base) 1415 return true; 1416 } 1417 1418 return false; 1419 } 1420 1421 static RegionOffset calculateOffset(const MemRegion *R) { 1422 const MemRegion *SymbolicOffsetBase = nullptr; 1423 int64_t Offset = 0; 1424 1425 while (true) { 1426 switch (R->getKind()) { 1427 case MemRegion::CodeSpaceRegionKind: 1428 case MemRegion::StackLocalsSpaceRegionKind: 1429 case MemRegion::StackArgumentsSpaceRegionKind: 1430 case MemRegion::HeapSpaceRegionKind: 1431 case MemRegion::UnknownSpaceRegionKind: 1432 case MemRegion::StaticGlobalSpaceRegionKind: 1433 case MemRegion::GlobalInternalSpaceRegionKind: 1434 case MemRegion::GlobalSystemSpaceRegionKind: 1435 case MemRegion::GlobalImmutableSpaceRegionKind: 1436 // Stores can bind directly to a region space to set a default value. 1437 assert(Offset == 0 && !SymbolicOffsetBase); 1438 goto Finish; 1439 1440 case MemRegion::FunctionCodeRegionKind: 1441 case MemRegion::BlockCodeRegionKind: 1442 case MemRegion::BlockDataRegionKind: 1443 // These will never have bindings, but may end up having values requested 1444 // if the user does some strange casting. 1445 if (Offset != 0) 1446 SymbolicOffsetBase = R; 1447 goto Finish; 1448 1449 case MemRegion::SymbolicRegionKind: 1450 case MemRegion::AllocaRegionKind: 1451 case MemRegion::CompoundLiteralRegionKind: 1452 case MemRegion::CXXThisRegionKind: 1453 case MemRegion::StringRegionKind: 1454 case MemRegion::ObjCStringRegionKind: 1455 case MemRegion::NonParamVarRegionKind: 1456 case MemRegion::ParamVarRegionKind: 1457 case MemRegion::CXXTempObjectRegionKind: 1458 // Usual base regions. 1459 goto Finish; 1460 1461 case MemRegion::ObjCIvarRegionKind: 1462 // This is a little strange, but it's a compromise between 1463 // ObjCIvarRegions having unknown compile-time offsets (when using the 1464 // non-fragile runtime) and yet still being distinct, non-overlapping 1465 // regions. Thus we treat them as "like" base regions for the purposes 1466 // of computing offsets. 1467 goto Finish; 1468 1469 case MemRegion::CXXBaseObjectRegionKind: { 1470 const auto *BOR = cast<CXXBaseObjectRegion>(R); 1471 R = BOR->getSuperRegion(); 1472 1473 QualType Ty; 1474 bool RootIsSymbolic = false; 1475 if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) { 1476 Ty = TVR->getDesugaredValueType(R->getContext()); 1477 } else if (const auto *SR = dyn_cast<SymbolicRegion>(R)) { 1478 // If our base region is symbolic, we don't know what type it really is. 1479 // Pretend the type of the symbol is the true dynamic type. 1480 // (This will at least be self-consistent for the life of the symbol.) 1481 Ty = SR->getSymbol()->getType()->getPointeeType(); 1482 RootIsSymbolic = true; 1483 } 1484 1485 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 1486 if (!Child) { 1487 // We cannot compute the offset of the base class. 1488 SymbolicOffsetBase = R; 1489 } else { 1490 if (RootIsSymbolic) { 1491 // Base layers on symbolic regions may not be type-correct. 1492 // Double-check the inheritance here, and revert to a symbolic offset 1493 // if it's invalid (e.g. due to a reinterpret_cast). 1494 if (BOR->isVirtual()) { 1495 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) 1496 SymbolicOffsetBase = R; 1497 } else { 1498 if (!isImmediateBase(Child, BOR->getDecl())) 1499 SymbolicOffsetBase = R; 1500 } 1501 } 1502 } 1503 1504 // Don't bother calculating precise offsets if we already have a 1505 // symbolic offset somewhere in the chain. 1506 if (SymbolicOffsetBase) 1507 continue; 1508 1509 CharUnits BaseOffset; 1510 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child); 1511 if (BOR->isVirtual()) 1512 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl()); 1513 else 1514 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl()); 1515 1516 // The base offset is in chars, not in bits. 1517 Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth(); 1518 break; 1519 } 1520 1521 case MemRegion::CXXDerivedObjectRegionKind: { 1522 // TODO: Store the base type in the CXXDerivedObjectRegion and use it. 1523 goto Finish; 1524 } 1525 1526 case MemRegion::ElementRegionKind: { 1527 const auto *ER = cast<ElementRegion>(R); 1528 R = ER->getSuperRegion(); 1529 1530 QualType EleTy = ER->getValueType(); 1531 if (EleTy->isIncompleteType()) { 1532 // We cannot compute the offset of the base class. 1533 SymbolicOffsetBase = R; 1534 continue; 1535 } 1536 1537 SVal Index = ER->getIndex(); 1538 if (Optional<nonloc::ConcreteInt> CI = 1539 Index.getAs<nonloc::ConcreteInt>()) { 1540 // Don't bother calculating precise offsets if we already have a 1541 // symbolic offset somewhere in the chain. 1542 if (SymbolicOffsetBase) 1543 continue; 1544 1545 int64_t i = CI->getValue().getSExtValue(); 1546 // This type size is in bits. 1547 Offset += i * R->getContext().getTypeSize(EleTy); 1548 } else { 1549 // We cannot compute offset for non-concrete index. 1550 SymbolicOffsetBase = R; 1551 } 1552 break; 1553 } 1554 case MemRegion::FieldRegionKind: { 1555 const auto *FR = cast<FieldRegion>(R); 1556 R = FR->getSuperRegion(); 1557 assert(R); 1558 1559 const RecordDecl *RD = FR->getDecl()->getParent(); 1560 if (RD->isUnion() || !RD->isCompleteDefinition()) { 1561 // We cannot compute offset for incomplete type. 1562 // For unions, we could treat everything as offset 0, but we'd rather 1563 // treat each field as a symbolic offset so they aren't stored on top 1564 // of each other, since we depend on things in typed regions actually 1565 // matching their types. 1566 SymbolicOffsetBase = R; 1567 } 1568 1569 // Don't bother calculating precise offsets if we already have a 1570 // symbolic offset somewhere in the chain. 1571 if (SymbolicOffsetBase) 1572 continue; 1573 1574 // Get the field number. 1575 unsigned idx = 0; 1576 for (RecordDecl::field_iterator FI = RD->field_begin(), 1577 FE = RD->field_end(); FI != FE; ++FI, ++idx) { 1578 if (FR->getDecl() == *FI) 1579 break; 1580 } 1581 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD); 1582 // This is offset in bits. 1583 Offset += Layout.getFieldOffset(idx); 1584 break; 1585 } 1586 } 1587 } 1588 1589 Finish: 1590 if (SymbolicOffsetBase) 1591 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 1592 return RegionOffset(R, Offset); 1593 } 1594 1595 RegionOffset MemRegion::getAsOffset() const { 1596 if (!cachedOffset) 1597 cachedOffset = calculateOffset(this); 1598 return *cachedOffset; 1599 } 1600 1601 //===----------------------------------------------------------------------===// 1602 // BlockDataRegion 1603 //===----------------------------------------------------------------------===// 1604 1605 std::pair<const VarRegion *, const VarRegion *> 1606 BlockDataRegion::getCaptureRegions(const VarDecl *VD) { 1607 MemRegionManager &MemMgr = getMemRegionManager(); 1608 const VarRegion *VR = nullptr; 1609 const VarRegion *OriginalVR = nullptr; 1610 1611 if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) { 1612 VR = MemMgr.getNonParamVarRegion(VD, this); 1613 OriginalVR = MemMgr.getVarRegion(VD, LC); 1614 } 1615 else { 1616 if (LC) { 1617 VR = MemMgr.getVarRegion(VD, LC); 1618 OriginalVR = VR; 1619 } 1620 else { 1621 VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion()); 1622 OriginalVR = MemMgr.getVarRegion(VD, LC); 1623 } 1624 } 1625 return std::make_pair(VR, OriginalVR); 1626 } 1627 1628 void BlockDataRegion::LazyInitializeReferencedVars() { 1629 if (ReferencedVars) 1630 return; 1631 1632 AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 1633 const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl()); 1634 auto NumBlockVars = 1635 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end()); 1636 1637 if (NumBlockVars == 0) { 1638 ReferencedVars = (void*) 0x1; 1639 return; 1640 } 1641 1642 MemRegionManager &MemMgr = getMemRegionManager(); 1643 llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 1644 BumpVectorContext BC(A); 1645 1646 using VarVec = BumpVector<const MemRegion *>; 1647 1648 auto *BV = A.Allocate<VarVec>(); 1649 new (BV) VarVec(BC, NumBlockVars); 1650 auto *BVOriginal = A.Allocate<VarVec>(); 1651 new (BVOriginal) VarVec(BC, NumBlockVars); 1652 1653 for (const auto *VD : ReferencedBlockVars) { 1654 const VarRegion *VR = nullptr; 1655 const VarRegion *OriginalVR = nullptr; 1656 std::tie(VR, OriginalVR) = getCaptureRegions(VD); 1657 assert(VR); 1658 assert(OriginalVR); 1659 BV->push_back(VR, BC); 1660 BVOriginal->push_back(OriginalVR, BC); 1661 } 1662 1663 ReferencedVars = BV; 1664 OriginalVars = BVOriginal; 1665 } 1666 1667 BlockDataRegion::referenced_vars_iterator 1668 BlockDataRegion::referenced_vars_begin() const { 1669 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1670 1671 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars); 1672 1673 if (Vec == (void*) 0x1) 1674 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr); 1675 1676 auto *VecOriginal = 1677 static_cast<BumpVector<const MemRegion *> *>(OriginalVars); 1678 1679 return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 1680 VecOriginal->begin()); 1681 } 1682 1683 BlockDataRegion::referenced_vars_iterator 1684 BlockDataRegion::referenced_vars_end() const { 1685 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1686 1687 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars); 1688 1689 if (Vec == (void*) 0x1) 1690 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr); 1691 1692 auto *VecOriginal = 1693 static_cast<BumpVector<const MemRegion *> *>(OriginalVars); 1694 1695 return BlockDataRegion::referenced_vars_iterator(Vec->end(), 1696 VecOriginal->end()); 1697 } 1698 1699 const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 1700 for (referenced_vars_iterator I = referenced_vars_begin(), 1701 E = referenced_vars_end(); 1702 I != E; ++I) { 1703 if (I.getCapturedRegion() == R) 1704 return I.getOriginalRegion(); 1705 } 1706 return nullptr; 1707 } 1708 1709 //===----------------------------------------------------------------------===// 1710 // RegionAndSymbolInvalidationTraits 1711 //===----------------------------------------------------------------------===// 1712 1713 void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym, 1714 InvalidationKinds IK) { 1715 SymTraitsMap[Sym] |= IK; 1716 } 1717 1718 void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR, 1719 InvalidationKinds IK) { 1720 assert(MR); 1721 if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) 1722 setTrait(SR->getSymbol(), IK); 1723 else 1724 MRTraitsMap[MR] |= IK; 1725 } 1726 1727 bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym, 1728 InvalidationKinds IK) const { 1729 const_symbol_iterator I = SymTraitsMap.find(Sym); 1730 if (I != SymTraitsMap.end()) 1731 return I->second & IK; 1732 1733 return false; 1734 } 1735 1736 bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR, 1737 InvalidationKinds IK) const { 1738 if (!MR) 1739 return false; 1740 1741 if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) 1742 return hasTrait(SR->getSymbol(), IK); 1743 1744 const_region_iterator I = MRTraitsMap.find(MR); 1745 if (I != MRTraitsMap.end()) 1746 return I->second & IK; 1747 1748 return false; 1749 } 1750