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