1 //== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines MemRegion and its subclasses. MemRegion defines a 11 // partially-typed abstraction of memory useful for path-sensitive dataflow 12 // analyses. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 17 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 18 #include "clang/Analysis/AnalysisContext.h" 19 #include "clang/Analysis/Support/BumpVector.h" 20 #include "clang/AST/CharUnits.h" 21 #include "clang/AST/RecordLayout.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 using namespace clang; 25 using namespace ento; 26 27 //===----------------------------------------------------------------------===// 28 // MemRegion Construction. 29 //===----------------------------------------------------------------------===// 30 31 template<typename RegionTy> struct MemRegionManagerTrait; 32 33 template <typename RegionTy, typename A1> 34 RegionTy* MemRegionManager::getRegion(const A1 a1) { 35 36 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 37 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); 38 39 llvm::FoldingSetNodeID ID; 40 RegionTy::ProfileRegion(ID, a1, superRegion); 41 void* InsertPos; 42 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 43 InsertPos)); 44 45 if (!R) { 46 R = (RegionTy*) A.Allocate<RegionTy>(); 47 new (R) RegionTy(a1, superRegion); 48 Regions.InsertNode(R, InsertPos); 49 } 50 51 return R; 52 } 53 54 template <typename RegionTy, typename A1> 55 RegionTy* MemRegionManager::getSubRegion(const A1 a1, 56 const MemRegion *superRegion) { 57 llvm::FoldingSetNodeID ID; 58 RegionTy::ProfileRegion(ID, a1, superRegion); 59 void* InsertPos; 60 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 61 InsertPos)); 62 63 if (!R) { 64 R = (RegionTy*) A.Allocate<RegionTy>(); 65 new (R) RegionTy(a1, superRegion); 66 Regions.InsertNode(R, InsertPos); 67 } 68 69 return R; 70 } 71 72 template <typename RegionTy, typename A1, typename A2> 73 RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) { 74 75 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 76 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2); 77 78 llvm::FoldingSetNodeID ID; 79 RegionTy::ProfileRegion(ID, a1, a2, superRegion); 80 void* InsertPos; 81 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 82 InsertPos)); 83 84 if (!R) { 85 R = (RegionTy*) A.Allocate<RegionTy>(); 86 new (R) RegionTy(a1, a2, superRegion); 87 Regions.InsertNode(R, InsertPos); 88 } 89 90 return R; 91 } 92 93 template <typename RegionTy, typename A1, typename A2> 94 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, 95 const MemRegion *superRegion) { 96 97 llvm::FoldingSetNodeID ID; 98 RegionTy::ProfileRegion(ID, a1, a2, superRegion); 99 void* InsertPos; 100 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 101 InsertPos)); 102 103 if (!R) { 104 R = (RegionTy*) A.Allocate<RegionTy>(); 105 new (R) RegionTy(a1, a2, superRegion); 106 Regions.InsertNode(R, InsertPos); 107 } 108 109 return R; 110 } 111 112 template <typename RegionTy, typename A1, typename A2, typename A3> 113 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3, 114 const MemRegion *superRegion) { 115 116 llvm::FoldingSetNodeID ID; 117 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion); 118 void* InsertPos; 119 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 120 InsertPos)); 121 122 if (!R) { 123 R = (RegionTy*) A.Allocate<RegionTy>(); 124 new (R) RegionTy(a1, a2, a3, superRegion); 125 Regions.InsertNode(R, InsertPos); 126 } 127 128 return R; 129 } 130 131 //===----------------------------------------------------------------------===// 132 // Object destruction. 133 //===----------------------------------------------------------------------===// 134 135 MemRegion::~MemRegion() {} 136 137 MemRegionManager::~MemRegionManager() { 138 // All regions and their data are BumpPtrAllocated. No need to call 139 // their destructors. 140 } 141 142 //===----------------------------------------------------------------------===// 143 // Basic methods. 144 //===----------------------------------------------------------------------===// 145 146 bool SubRegion::isSubRegionOf(const MemRegion* R) const { 147 const MemRegion* r = getSuperRegion(); 148 while (r != 0) { 149 if (r == R) 150 return true; 151 if (const SubRegion* sr = dyn_cast<SubRegion>(r)) 152 r = sr->getSuperRegion(); 153 else 154 break; 155 } 156 return false; 157 } 158 159 MemRegionManager* SubRegion::getMemRegionManager() const { 160 const SubRegion* r = this; 161 do { 162 const MemRegion *superRegion = r->getSuperRegion(); 163 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) { 164 r = sr; 165 continue; 166 } 167 return superRegion->getMemRegionManager(); 168 } while (1); 169 } 170 171 const StackFrameContext *VarRegion::getStackFrame() const { 172 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace()); 173 return SSR ? SSR->getStackFrame() : NULL; 174 } 175 176 //===----------------------------------------------------------------------===// 177 // Region extents. 178 //===----------------------------------------------------------------------===// 179 180 DefinedOrUnknownSVal DeclRegion::getExtent(SValBuilder &svalBuilder) const { 181 ASTContext& Ctx = svalBuilder.getContext(); 182 QualType T = getDesugaredValueType(Ctx); 183 184 if (isa<VariableArrayType>(T)) 185 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 186 if (isa<IncompleteArrayType>(T)) 187 return UnknownVal(); 188 189 CharUnits size = Ctx.getTypeSizeInChars(T); 190 QualType sizeTy = svalBuilder.getArrayIndexType(); 191 return svalBuilder.makeIntVal(size.getQuantity(), sizeTy); 192 } 193 194 DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const { 195 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder); 196 197 // A zero-length array at the end of a struct often stands for dynamically- 198 // allocated extra memory. 199 if (Extent.isZeroConstant()) { 200 QualType T = getDesugaredValueType(svalBuilder.getContext()); 201 202 if (isa<ConstantArrayType>(T)) 203 return UnknownVal(); 204 } 205 206 return Extent; 207 } 208 209 DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const { 210 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 211 } 212 213 DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const { 214 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 215 } 216 217 DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const { 218 return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1, 219 svalBuilder.getArrayIndexType()); 220 } 221 222 QualType CXXBaseObjectRegion::getValueType() const { 223 return QualType(decl->getTypeForDecl(), 0); 224 } 225 226 //===----------------------------------------------------------------------===// 227 // FoldingSet profiling. 228 //===----------------------------------------------------------------------===// 229 230 void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const { 231 ID.AddInteger((unsigned)getKind()); 232 } 233 234 void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 235 ID.AddInteger((unsigned)getKind()); 236 ID.AddPointer(getStackFrame()); 237 } 238 239 void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 240 ID.AddInteger((unsigned)getKind()); 241 ID.AddPointer(getCodeRegion()); 242 } 243 244 void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 245 const StringLiteral* Str, 246 const MemRegion* superRegion) { 247 ID.AddInteger((unsigned) StringRegionKind); 248 ID.AddPointer(Str); 249 ID.AddPointer(superRegion); 250 } 251 252 void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 253 const Expr* Ex, unsigned cnt, 254 const MemRegion *) { 255 ID.AddInteger((unsigned) AllocaRegionKind); 256 ID.AddPointer(Ex); 257 ID.AddInteger(cnt); 258 } 259 260 void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const { 261 ProfileRegion(ID, Ex, Cnt, superRegion); 262 } 263 264 void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const { 265 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion); 266 } 267 268 void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 269 const CompoundLiteralExpr* CL, 270 const MemRegion* superRegion) { 271 ID.AddInteger((unsigned) CompoundLiteralRegionKind); 272 ID.AddPointer(CL); 273 ID.AddPointer(superRegion); 274 } 275 276 void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 277 const PointerType *PT, 278 const MemRegion *sRegion) { 279 ID.AddInteger((unsigned) CXXThisRegionKind); 280 ID.AddPointer(PT); 281 ID.AddPointer(sRegion); 282 } 283 284 void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const { 285 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion); 286 } 287 288 void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, 289 const MemRegion* superRegion, Kind k) { 290 ID.AddInteger((unsigned) k); 291 ID.AddPointer(D); 292 ID.AddPointer(superRegion); 293 } 294 295 void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const { 296 DeclRegion::ProfileRegion(ID, D, superRegion, getKind()); 297 } 298 299 void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const { 300 VarRegion::ProfileRegion(ID, getDecl(), superRegion); 301 } 302 303 void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym, 304 const MemRegion *sreg) { 305 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind); 306 ID.Add(sym); 307 ID.AddPointer(sreg); 308 } 309 310 void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const { 311 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion()); 312 } 313 314 void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 315 QualType ElementType, SVal Idx, 316 const MemRegion* superRegion) { 317 ID.AddInteger(MemRegion::ElementRegionKind); 318 ID.Add(ElementType); 319 ID.AddPointer(superRegion); 320 Idx.Profile(ID); 321 } 322 323 void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { 324 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion); 325 } 326 327 void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 328 const FunctionDecl *FD, 329 const MemRegion*) { 330 ID.AddInteger(MemRegion::FunctionTextRegionKind); 331 ID.AddPointer(FD); 332 } 333 334 void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 335 FunctionTextRegion::ProfileRegion(ID, FD, superRegion); 336 } 337 338 void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 339 const BlockDecl *BD, CanQualType, 340 const AnalysisContext *AC, 341 const MemRegion*) { 342 ID.AddInteger(MemRegion::BlockTextRegionKind); 343 ID.AddPointer(BD); 344 } 345 346 void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 347 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion); 348 } 349 350 void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 351 const BlockTextRegion *BC, 352 const LocationContext *LC, 353 const MemRegion *sReg) { 354 ID.AddInteger(MemRegion::BlockDataRegionKind); 355 ID.AddPointer(BC); 356 ID.AddPointer(LC); 357 ID.AddPointer(sReg); 358 } 359 360 void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const { 361 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion()); 362 } 363 364 void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 365 Expr const *Ex, 366 const MemRegion *sReg) { 367 ID.AddPointer(Ex); 368 ID.AddPointer(sReg); 369 } 370 371 void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 372 ProfileRegion(ID, Ex, getSuperRegion()); 373 } 374 375 void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 376 const CXXRecordDecl *decl, 377 const MemRegion *sReg) { 378 ID.AddPointer(decl); 379 ID.AddPointer(sReg); 380 } 381 382 void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 383 ProfileRegion(ID, decl, superRegion); 384 } 385 386 //===----------------------------------------------------------------------===// 387 // Region pretty-printing. 388 //===----------------------------------------------------------------------===// 389 390 void MemRegion::dump() const { 391 dumpToStream(llvm::errs()); 392 } 393 394 std::string MemRegion::getString() const { 395 std::string s; 396 llvm::raw_string_ostream os(s); 397 dumpToStream(os); 398 return os.str(); 399 } 400 401 void MemRegion::dumpToStream(llvm::raw_ostream& os) const { 402 os << "<Unknown Region>"; 403 } 404 405 void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const { 406 os << "alloca{" << (void*) Ex << ',' << Cnt << '}'; 407 } 408 409 void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const { 410 os << "code{" << getDecl()->getDeclName().getAsString() << '}'; 411 } 412 413 void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const { 414 os << "block_code{" << (void*) this << '}'; 415 } 416 417 void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const { 418 os << "block_data{" << BC << '}'; 419 } 420 421 void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const { 422 // FIXME: More elaborate pretty-printing. 423 os << "{ " << (void*) CL << " }"; 424 } 425 426 void CXXTempObjectRegion::dumpToStream(llvm::raw_ostream &os) const { 427 os << "temp_object"; 428 } 429 430 void CXXBaseObjectRegion::dumpToStream(llvm::raw_ostream &os) const { 431 os << "base " << decl->getName(); 432 } 433 434 void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const { 435 os << "this"; 436 } 437 438 void ElementRegion::dumpToStream(llvm::raw_ostream& os) const { 439 os << "element{" << superRegion << ',' 440 << Index << ',' << getElementType().getAsString() << '}'; 441 } 442 443 void FieldRegion::dumpToStream(llvm::raw_ostream& os) const { 444 os << superRegion << "->" << getDecl(); 445 } 446 447 void NonStaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const { 448 os << "NonStaticGlobalSpaceRegion"; 449 } 450 451 void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const { 452 os << "ivar{" << superRegion << ',' << getDecl() << '}'; 453 } 454 455 void StringRegion::dumpToStream(llvm::raw_ostream& os) const { 456 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions())); 457 } 458 459 void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const { 460 os << "SymRegion{" << sym << '}'; 461 } 462 463 void VarRegion::dumpToStream(llvm::raw_ostream& os) const { 464 os << cast<VarDecl>(D); 465 } 466 467 void RegionRawOffset::dump() const { 468 dumpToStream(llvm::errs()); 469 } 470 471 void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const { 472 os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}'; 473 } 474 475 void StaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const { 476 os << "StaticGlobalsMemSpace{" << CR << '}'; 477 } 478 479 //===----------------------------------------------------------------------===// 480 // MemRegionManager methods. 481 //===----------------------------------------------------------------------===// 482 483 template <typename REG> 484 const REG *MemRegionManager::LazyAllocate(REG*& region) { 485 if (!region) { 486 region = (REG*) A.Allocate<REG>(); 487 new (region) REG(this); 488 } 489 490 return region; 491 } 492 493 template <typename REG, typename ARG> 494 const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { 495 if (!region) { 496 region = (REG*) A.Allocate<REG>(); 497 new (region) REG(this, a); 498 } 499 500 return region; 501 } 502 503 const StackLocalsSpaceRegion* 504 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { 505 assert(STC); 506 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC]; 507 508 if (R) 509 return R; 510 511 R = A.Allocate<StackLocalsSpaceRegion>(); 512 new (R) StackLocalsSpaceRegion(this, STC); 513 return R; 514 } 515 516 const StackArgumentsSpaceRegion * 517 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { 518 assert(STC); 519 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC]; 520 521 if (R) 522 return R; 523 524 R = A.Allocate<StackArgumentsSpaceRegion>(); 525 new (R) StackArgumentsSpaceRegion(this, STC); 526 return R; 527 } 528 529 const GlobalsSpaceRegion 530 *MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) { 531 if (!CR) 532 return LazyAllocate(globals); 533 534 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; 535 if (R) 536 return R; 537 538 R = A.Allocate<StaticGlobalSpaceRegion>(); 539 new (R) StaticGlobalSpaceRegion(this, CR); 540 return R; 541 } 542 543 const HeapSpaceRegion *MemRegionManager::getHeapRegion() { 544 return LazyAllocate(heap); 545 } 546 547 const MemSpaceRegion *MemRegionManager::getUnknownRegion() { 548 return LazyAllocate(unknown); 549 } 550 551 const MemSpaceRegion *MemRegionManager::getCodeRegion() { 552 return LazyAllocate(code); 553 } 554 555 //===----------------------------------------------------------------------===// 556 // Constructing regions. 557 //===----------------------------------------------------------------------===// 558 559 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){ 560 return getSubRegion<StringRegion>(Str, getGlobalsRegion()); 561 } 562 563 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, 564 const LocationContext *LC) { 565 const MemRegion *sReg = 0; 566 567 if (D->hasGlobalStorage() && !D->isStaticLocal()) 568 sReg = getGlobalsRegion(); 569 else { 570 // FIXME: Once we implement scope handling, we will need to properly lookup 571 // 'D' to the proper LocationContext. 572 const DeclContext *DC = D->getDeclContext(); 573 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC); 574 575 if (!STC) 576 sReg = getUnknownRegion(); 577 else { 578 if (D->hasLocalStorage()) { 579 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) 580 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) 581 : static_cast<const MemRegion*>(getStackLocalsRegion(STC)); 582 } 583 else { 584 assert(D->isStaticLocal()); 585 const Decl *D = STC->getDecl(); 586 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 587 sReg = getGlobalsRegion(getFunctionTextRegion(FD)); 588 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 589 const BlockTextRegion *BTR = 590 getBlockTextRegion(BD, 591 C.getCanonicalType(BD->getSignatureAsWritten()->getType()), 592 STC->getAnalysisContext()); 593 sReg = getGlobalsRegion(BTR); 594 } 595 else { 596 // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now 597 // just use the main global memspace. 598 sReg = getGlobalsRegion(); 599 } 600 } 601 } 602 } 603 604 return getSubRegion<VarRegion>(D, sReg); 605 } 606 607 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, 608 const MemRegion *superR) { 609 return getSubRegion<VarRegion>(D, superR); 610 } 611 612 const BlockDataRegion * 613 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, 614 const LocationContext *LC) { 615 const MemRegion *sReg = 0; 616 617 if (LC) { 618 // FIXME: Once we implement scope handling, we want the parent region 619 // to be the scope. 620 const StackFrameContext *STC = LC->getCurrentStackFrame(); 621 assert(STC); 622 sReg = getStackLocalsRegion(STC); 623 } 624 else { 625 // We allow 'LC' to be NULL for cases where want BlockDataRegions 626 // without context-sensitivity. 627 sReg = getUnknownRegion(); 628 } 629 630 return getSubRegion<BlockDataRegion>(BC, LC, sReg); 631 } 632 633 const CompoundLiteralRegion* 634 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL, 635 const LocationContext *LC) { 636 637 const MemRegion *sReg = 0; 638 639 if (CL->isFileScope()) 640 sReg = getGlobalsRegion(); 641 else { 642 const StackFrameContext *STC = LC->getCurrentStackFrame(); 643 assert(STC); 644 sReg = getStackLocalsRegion(STC); 645 } 646 647 return getSubRegion<CompoundLiteralRegion>(CL, sReg); 648 } 649 650 const ElementRegion* 651 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, 652 const MemRegion* superRegion, 653 ASTContext& Ctx){ 654 655 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 656 657 llvm::FoldingSetNodeID ID; 658 ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 659 660 void* InsertPos; 661 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); 662 ElementRegion* R = cast_or_null<ElementRegion>(data); 663 664 if (!R) { 665 R = (ElementRegion*) A.Allocate<ElementRegion>(); 666 new (R) ElementRegion(T, Idx, superRegion); 667 Regions.InsertNode(R, InsertPos); 668 } 669 670 return R; 671 } 672 673 const FunctionTextRegion * 674 MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) { 675 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); 676 } 677 678 const BlockTextRegion * 679 MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, 680 AnalysisContext *AC) { 681 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion()); 682 } 683 684 685 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 686 const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { 687 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); 688 } 689 690 const FieldRegion* 691 MemRegionManager::getFieldRegion(const FieldDecl* d, 692 const MemRegion* superRegion){ 693 return getSubRegion<FieldRegion>(d, superRegion); 694 } 695 696 const ObjCIvarRegion* 697 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d, 698 const MemRegion* superRegion) { 699 return getSubRegion<ObjCIvarRegion>(d, superRegion); 700 } 701 702 const CXXTempObjectRegion* 703 MemRegionManager::getCXXTempObjectRegion(Expr const *E, 704 LocationContext const *LC) { 705 const StackFrameContext *SFC = LC->getCurrentStackFrame(); 706 assert(SFC); 707 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC)); 708 } 709 710 const CXXBaseObjectRegion * 711 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl, 712 const MemRegion *superRegion) { 713 return getSubRegion<CXXBaseObjectRegion>(decl, superRegion); 714 } 715 716 const CXXThisRegion* 717 MemRegionManager::getCXXThisRegion(QualType thisPointerTy, 718 const LocationContext *LC) { 719 const StackFrameContext *STC = LC->getCurrentStackFrame(); 720 assert(STC); 721 const PointerType *PT = thisPointerTy->getAs<PointerType>(); 722 assert(PT); 723 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC)); 724 } 725 726 const AllocaRegion* 727 MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt, 728 const LocationContext *LC) { 729 const StackFrameContext *STC = LC->getCurrentStackFrame(); 730 assert(STC); 731 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC)); 732 } 733 734 const MemSpaceRegion *MemRegion::getMemorySpace() const { 735 const MemRegion *R = this; 736 const SubRegion* SR = dyn_cast<SubRegion>(this); 737 738 while (SR) { 739 R = SR->getSuperRegion(); 740 SR = dyn_cast<SubRegion>(R); 741 } 742 743 return dyn_cast<MemSpaceRegion>(R); 744 } 745 746 bool MemRegion::hasStackStorage() const { 747 return isa<StackSpaceRegion>(getMemorySpace()); 748 } 749 750 bool MemRegion::hasStackNonParametersStorage() const { 751 return isa<StackLocalsSpaceRegion>(getMemorySpace()); 752 } 753 754 bool MemRegion::hasStackParametersStorage() const { 755 return isa<StackArgumentsSpaceRegion>(getMemorySpace()); 756 } 757 758 bool MemRegion::hasGlobalsOrParametersStorage() const { 759 const MemSpaceRegion *MS = getMemorySpace(); 760 return isa<StackArgumentsSpaceRegion>(MS) || 761 isa<GlobalsSpaceRegion>(MS); 762 } 763 764 // getBaseRegion strips away all elements and fields, and get the base region 765 // of them. 766 const MemRegion *MemRegion::getBaseRegion() const { 767 const MemRegion *R = this; 768 while (true) { 769 switch (R->getKind()) { 770 case MemRegion::ElementRegionKind: 771 case MemRegion::FieldRegionKind: 772 case MemRegion::ObjCIvarRegionKind: 773 case MemRegion::CXXBaseObjectRegionKind: 774 R = cast<SubRegion>(R)->getSuperRegion(); 775 continue; 776 default: 777 break; 778 } 779 break; 780 } 781 return R; 782 } 783 784 //===----------------------------------------------------------------------===// 785 // View handling. 786 //===----------------------------------------------------------------------===// 787 788 const MemRegion *MemRegion::StripCasts() const { 789 const MemRegion *R = this; 790 while (true) { 791 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 792 // FIXME: generalize. Essentially we want to strip away ElementRegions 793 // that were layered on a symbolic region because of casts. We only 794 // want to strip away ElementRegions, however, where the index is 0. 795 SVal index = ER->getIndex(); 796 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) { 797 if (CI->getValue().getSExtValue() == 0) { 798 R = ER->getSuperRegion(); 799 continue; 800 } 801 } 802 } 803 break; 804 } 805 return R; 806 } 807 808 // FIXME: Merge with the implementation of the same method in Store.cpp 809 static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { 810 if (const RecordType *RT = Ty->getAs<RecordType>()) { 811 const RecordDecl *D = RT->getDecl(); 812 if (!D->getDefinition()) 813 return false; 814 } 815 816 return true; 817 } 818 819 RegionRawOffset ElementRegion::getAsArrayOffset() const { 820 CharUnits offset = CharUnits::Zero(); 821 const ElementRegion *ER = this; 822 const MemRegion *superR = NULL; 823 ASTContext &C = getContext(); 824 825 // FIXME: Handle multi-dimensional arrays. 826 827 while (ER) { 828 superR = ER->getSuperRegion(); 829 830 // FIXME: generalize to symbolic offsets. 831 SVal index = ER->getIndex(); 832 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) { 833 // Update the offset. 834 int64_t i = CI->getValue().getSExtValue(); 835 836 if (i != 0) { 837 QualType elemType = ER->getElementType(); 838 839 // If we are pointing to an incomplete type, go no further. 840 if (!IsCompleteType(C, elemType)) { 841 superR = ER; 842 break; 843 } 844 845 CharUnits size = C.getTypeSizeInChars(elemType); 846 offset += (i * size); 847 } 848 849 // Go to the next ElementRegion (if any). 850 ER = dyn_cast<ElementRegion>(superR); 851 continue; 852 } 853 854 return NULL; 855 } 856 857 assert(superR && "super region cannot be NULL"); 858 return RegionRawOffset(superR, offset); 859 } 860 861 RegionOffset MemRegion::getAsOffset() const { 862 const MemRegion *R = this; 863 int64_t Offset = 0; 864 865 while (1) { 866 switch (R->getKind()) { 867 default: 868 return RegionOffset(0); 869 case SymbolicRegionKind: 870 case AllocaRegionKind: 871 case CompoundLiteralRegionKind: 872 case CXXThisRegionKind: 873 case StringRegionKind: 874 case VarRegionKind: 875 case CXXTempObjectRegionKind: 876 goto Finish; 877 case ElementRegionKind: { 878 const ElementRegion *ER = cast<ElementRegion>(R); 879 QualType EleTy = ER->getValueType(); 880 881 if (!IsCompleteType(getContext(), EleTy)) 882 return RegionOffset(0); 883 884 SVal Index = ER->getIndex(); 885 if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) { 886 int64_t i = CI->getValue().getSExtValue(); 887 CharUnits Size = getContext().getTypeSizeInChars(EleTy); 888 Offset += i * Size.getQuantity() * 8; 889 } else { 890 // We cannot compute offset for non-concrete index. 891 return RegionOffset(0); 892 } 893 R = ER->getSuperRegion(); 894 break; 895 } 896 case FieldRegionKind: { 897 const FieldRegion *FR = cast<FieldRegion>(R); 898 const RecordDecl *RD = FR->getDecl()->getParent(); 899 if (!RD->isDefinition()) 900 // We cannot compute offset for incomplete type. 901 return RegionOffset(0); 902 // Get the field number. 903 unsigned idx = 0; 904 for (RecordDecl::field_iterator FI = RD->field_begin(), 905 FE = RD->field_end(); FI != FE; ++FI, ++idx) 906 if (FR->getDecl() == *FI) 907 break; 908 909 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 910 // This is offset in bits. 911 Offset += Layout.getFieldOffset(idx); 912 R = FR->getSuperRegion(); 913 break; 914 } 915 } 916 } 917 918 Finish: 919 return RegionOffset(R, Offset); 920 } 921 922 //===----------------------------------------------------------------------===// 923 // BlockDataRegion 924 //===----------------------------------------------------------------------===// 925 926 void BlockDataRegion::LazyInitializeReferencedVars() { 927 if (ReferencedVars) 928 return; 929 930 AnalysisContext *AC = getCodeRegion()->getAnalysisContext(); 931 AnalysisContext::referenced_decls_iterator I, E; 932 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); 933 934 if (I == E) { 935 ReferencedVars = (void*) 0x1; 936 return; 937 } 938 939 MemRegionManager &MemMgr = *getMemRegionManager(); 940 llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 941 BumpVectorContext BC(A); 942 943 typedef BumpVector<const MemRegion*> VarVec; 944 VarVec *BV = (VarVec*) A.Allocate<VarVec>(); 945 new (BV) VarVec(BC, E - I); 946 947 for ( ; I != E; ++I) { 948 const VarDecl *VD = *I; 949 const VarRegion *VR = 0; 950 951 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) 952 VR = MemMgr.getVarRegion(VD, this); 953 else { 954 if (LC) 955 VR = MemMgr.getVarRegion(VD, LC); 956 else { 957 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 958 } 959 } 960 961 assert(VR); 962 BV->push_back(VR, BC); 963 } 964 965 ReferencedVars = BV; 966 } 967 968 BlockDataRegion::referenced_vars_iterator 969 BlockDataRegion::referenced_vars_begin() const { 970 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 971 972 BumpVector<const MemRegion*> *Vec = 973 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 974 975 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ? 976 NULL : Vec->begin()); 977 } 978 979 BlockDataRegion::referenced_vars_iterator 980 BlockDataRegion::referenced_vars_end() const { 981 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 982 983 BumpVector<const MemRegion*> *Vec = 984 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 985 986 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ? 987 NULL : Vec->end()); 988 } 989