1183170Simp//==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==// 2183170Simp// 3183170Simp// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4183170Simp// See https://llvm.org/LICENSE.txt for license information. 5183170Simp// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6183170Simp// 7183170Simp//===----------------------------------------------------------------------===// 8183170Simp// 9183170Simp// This file defines MemRegion and its subclasses. MemRegion defines a 10183170Simp// partially-typed abstraction of memory useful for path-sensitive dataflow 11183170Simp// analyses. 12183170Simp// 13183170Simp//===----------------------------------------------------------------------===// 14183170Simp 15183170Simp#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 16183170Simp#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 17183170Simp 18183170Simp#include "clang/AST/ASTContext.h" 19183170Simp#include "clang/AST/CharUnits.h" 20183170Simp#include "clang/AST/Decl.h" 21183170Simp#include "clang/AST/DeclObjC.h" 22183170Simp#include "clang/AST/DeclarationName.h" 23183170Simp#include "clang/AST/Expr.h" 24183170Simp#include "clang/AST/ExprObjC.h" 25183170Simp#include "clang/AST/Type.h" 26183170Simp#include "clang/Analysis/AnalysisDeclContext.h" 27183170Simp#include "clang/Basic/LLVM.h" 28183170Simp#include "clang/Basic/SourceLocation.h" 29178170Simp#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 30178170Simp#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" 31178170Simp#include "llvm/ADT/DenseMap.h" 32178170Simp#include "llvm/ADT/FoldingSet.h" 33178170Simp#include "llvm/ADT/Optional.h" 34178170Simp#include "llvm/ADT/PointerIntPair.h" 35201986Simp#include "llvm/Support/Allocator.h" 36201986Simp#include "llvm/Support/Casting.h" 37204305Simp#include <cassert> 38211280Sjchandra#include <cstdint> 39224115Sjchandra#include <limits> 40178170Simp#include <string> 41178170Simp#include <utility> 42178170Simp 43178170Simpnamespace clang { 44178170Simp 45178170Simpclass AnalysisDeclContext; 46178170Simpclass CXXRecordDecl; 47178170Simpclass Decl; 48178170Simpclass LocationContext; 49178170Simpclass StackFrameContext; 50178170Simp 51201986Simpnamespace ento { 52201986Simp 53178170Simpclass CodeTextRegion; 54201986Simpclass MemRegion; 55178170Simpclass MemRegionManager; 56178170Simpclass MemSpaceRegion; 57178170Simpclass SValBuilder; 58201986Simpclass SymbolicRegion; 59201986Simpclass VarRegion; 60201986Simp 61201986Simp/// Represent a region's offset within the top level base region. 62201986Simpclass RegionOffset { 63210311Sjmallett /// The base region. 64210311Sjmallett const MemRegion *R = nullptr; 65210311Sjmallett 66210311Sjmallett /// The bit offset within the base region. Can be negative. 67210311Sjmallett int64_t Offset; 68210311Sjmallett 69220355Sadrianpublic: 70220355Sadrian // We're using a const instead of an enumeration due to the size required; 71220355Sadrian // Visual Studio will only create enumerations of size int, not long long. 72220355Sadrian static const int64_t Symbolic = std::numeric_limits<int64_t>::max(); 73220355Sadrian 74223927Sray RegionOffset() = default; 75223927Sray RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 76223927Sray 77223927Sray const MemRegion *getRegion() const { return R; } 78223927Sray 79223927Sray bool hasSymbolicOffset() const { return Offset == Symbolic; } 80223927Sray 81223927Sray int64_t getOffset() const { 82 assert(!hasSymbolicOffset()); 83 return Offset; 84 } 85 86 bool isValid() const { return R; } 87}; 88 89//===----------------------------------------------------------------------===// 90// Base region classes. 91//===----------------------------------------------------------------------===// 92 93/// MemRegion - The root abstract class for all memory regions. 94class MemRegion : public llvm::FoldingSetNode { 95public: 96 enum Kind { 97#define REGION(Id, Parent) Id ## Kind, 98#define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, 99#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" 100 }; 101 102private: 103 const Kind kind; 104 mutable Optional<RegionOffset> cachedOffset; 105 106protected: 107 MemRegion(Kind k) : kind(k) {} 108 virtual ~MemRegion(); 109 110public: 111 ASTContext &getContext() const; 112 113 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 114 115 virtual MemRegionManager* getMemRegionManager() const = 0; 116 117 const MemSpaceRegion *getMemorySpace() const; 118 119 const MemRegion *getBaseRegion() const; 120 121 /// Recursively retrieve the region of the most derived class instance of 122 /// regions of C++ base class instances. 123 const MemRegion *getMostDerivedObjectRegion() const; 124 125 /// Check if the region is a subregion of the given region. 126 /// Each region is a subregion of itself. 127 virtual bool isSubRegionOf(const MemRegion *R) const; 128 129 const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const; 130 131 /// If this is a symbolic region, returns the region. Otherwise, 132 /// goes up the base chain looking for the first symbolic base region. 133 const SymbolicRegion *getSymbolicBase() const; 134 135 bool hasGlobalsOrParametersStorage() const; 136 137 bool hasStackStorage() const; 138 139 bool hasStackNonParametersStorage() const; 140 141 bool hasStackParametersStorage() const; 142 143 /// Compute the offset within the top level memory object. 144 RegionOffset getAsOffset() const; 145 146 /// Get a string representation of a region for debug use. 147 std::string getString() const; 148 149 virtual void dumpToStream(raw_ostream &os) const; 150 151 void dump() const; 152 153 /// Returns true if this region can be printed in a user-friendly way. 154 virtual bool canPrintPretty() const; 155 156 /// Print the region for use in diagnostics. 157 virtual void printPretty(raw_ostream &os) const; 158 159 /// Returns true if this region's textual representation can be used 160 /// as part of a larger expression. 161 virtual bool canPrintPrettyAsExpr() const; 162 163 /// Print the region as expression. 164 /// 165 /// When this region represents a subexpression, the method is for printing 166 /// an expression containing it. 167 virtual void printPrettyAsExpr(raw_ostream &os) const; 168 169 Kind getKind() const { return kind; } 170 171 template<typename RegionTy> const RegionTy* getAs() const; 172 template<typename RegionTy> const RegionTy* castAs() const; 173 174 virtual bool isBoundable() const { return false; } 175 176 /// Get descriptive name for memory region. The name is obtained from 177 /// the variable/field declaration retrieved from the memory region. 178 /// Regions that point to an element of an array are returned as: "arr[0]". 179 /// Regions that point to a struct are returned as: "st.var". 180 // 181 /// \param UseQuotes Set if the name should be quoted. 182 /// 183 /// \returns variable name for memory region 184 std::string getDescriptiveName(bool UseQuotes = true) const; 185 186 /// Retrieve source range from memory region. The range retrieval 187 /// is based on the decl obtained from the memory region. 188 /// For a VarRegion the range of the base region is returned. 189 /// For a FieldRegion the range of the field is returned. 190 /// If no declaration is found, an empty source range is returned. 191 /// The client is responsible for checking if the returned range is valid. 192 /// 193 /// \returns source range for declaration retrieved from memory region 194 SourceRange sourceRange() const; 195}; 196 197/// MemSpaceRegion - A memory region that represents a "memory space"; 198/// for example, the set of global variables, the stack frame, etc. 199class MemSpaceRegion : public MemRegion { 200protected: 201 MemRegionManager *Mgr; 202 203 MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) { 204 assert(classof(this)); 205 assert(mgr); 206 } 207 208 MemRegionManager* getMemRegionManager() const override { return Mgr; } 209 210public: 211 bool isBoundable() const override { return false; } 212 213 void Profile(llvm::FoldingSetNodeID &ID) const override; 214 215 static bool classof(const MemRegion *R) { 216 Kind k = R->getKind(); 217 return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES; 218 } 219}; 220 221/// CodeSpaceRegion - The memory space that holds the executable code of 222/// functions and blocks. 223class CodeSpaceRegion : public MemSpaceRegion { 224 friend class MemRegionManager; 225 226 CodeSpaceRegion(MemRegionManager *mgr) 227 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {} 228 229public: 230 void dumpToStream(raw_ostream &os) const override; 231 232 static bool classof(const MemRegion *R) { 233 return R->getKind() == CodeSpaceRegionKind; 234 } 235}; 236 237class GlobalsSpaceRegion : public MemSpaceRegion { 238 virtual void anchor(); 239 240protected: 241 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) { 242 assert(classof(this)); 243 } 244 245public: 246 static bool classof(const MemRegion *R) { 247 Kind k = R->getKind(); 248 return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 249 } 250}; 251 252/// The region of the static variables within the current CodeTextRegion 253/// scope. 254/// 255/// Currently, only the static locals are placed there, so we know that these 256/// variables do not get invalidated by calls to other functions. 257class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 258 friend class MemRegionManager; 259 260 const CodeTextRegion *CR; 261 262 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) 263 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) { 264 assert(cr); 265 } 266 267public: 268 void Profile(llvm::FoldingSetNodeID &ID) const override; 269 270 void dumpToStream(raw_ostream &os) const override; 271 272 const CodeTextRegion *getCodeRegion() const { return CR; } 273 274 static bool classof(const MemRegion *R) { 275 return R->getKind() == StaticGlobalSpaceRegionKind; 276 } 277}; 278 279/// The region for all the non-static global variables. 280/// 281/// This class is further split into subclasses for efficient implementation of 282/// invalidating a set of related global values as is done in 283/// RegionStoreManager::invalidateRegions (instead of finding all the dependent 284/// globals, we invalidate the whole parent region). 285class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 286 void anchor() override; 287 288protected: 289 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) 290 : GlobalsSpaceRegion(mgr, k) { 291 assert(classof(this)); 292 } 293 294public: 295 static bool classof(const MemRegion *R) { 296 Kind k = R->getKind(); 297 return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES && 298 k <= END_NON_STATIC_GLOBAL_MEMSPACES; 299 } 300}; 301 302/// The region containing globals which are defined in system/external 303/// headers and are considered modifiable by system calls (ex: errno). 304class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 305 friend class MemRegionManager; 306 307 GlobalSystemSpaceRegion(MemRegionManager *mgr) 308 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 309 310public: 311 void dumpToStream(raw_ostream &os) const override; 312 313 static bool classof(const MemRegion *R) { 314 return R->getKind() == GlobalSystemSpaceRegionKind; 315 } 316}; 317 318/// The region containing globals which are considered not to be modified 319/// or point to data which could be modified as a result of a function call 320/// (system or internal). Ex: Const global scalars would be modeled as part of 321/// this region. This region also includes most system globals since they have 322/// low chance of being modified. 323class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 324 friend class MemRegionManager; 325 326 GlobalImmutableSpaceRegion(MemRegionManager *mgr) 327 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 328 329public: 330 void dumpToStream(raw_ostream &os) const override; 331 332 static bool classof(const MemRegion *R) { 333 return R->getKind() == GlobalImmutableSpaceRegionKind; 334 } 335}; 336 337/// The region containing globals which can be modified by calls to 338/// "internally" defined functions - (for now just) functions other then system 339/// calls. 340class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 341 friend class MemRegionManager; 342 343 GlobalInternalSpaceRegion(MemRegionManager *mgr) 344 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 345 346public: 347 void dumpToStream(raw_ostream &os) const override; 348 349 static bool classof(const MemRegion *R) { 350 return R->getKind() == GlobalInternalSpaceRegionKind; 351 } 352}; 353 354class HeapSpaceRegion : public MemSpaceRegion { 355 friend class MemRegionManager; 356 357 HeapSpaceRegion(MemRegionManager *mgr) 358 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 359 360public: 361 void dumpToStream(raw_ostream &os) const override; 362 363 static bool classof(const MemRegion *R) { 364 return R->getKind() == HeapSpaceRegionKind; 365 } 366}; 367 368class UnknownSpaceRegion : public MemSpaceRegion { 369 friend class MemRegionManager; 370 371 UnknownSpaceRegion(MemRegionManager *mgr) 372 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 373 374public: 375 void dumpToStream(raw_ostream &os) const override; 376 377 static bool classof(const MemRegion *R) { 378 return R->getKind() == UnknownSpaceRegionKind; 379 } 380}; 381 382class StackSpaceRegion : public MemSpaceRegion { 383 virtual void anchor(); 384 385 const StackFrameContext *SFC; 386 387protected: 388 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) 389 : MemSpaceRegion(mgr, k), SFC(sfc) { 390 assert(classof(this)); 391 assert(sfc); 392 } 393 394public: 395 const StackFrameContext *getStackFrame() const { return SFC; } 396 397 void Profile(llvm::FoldingSetNodeID &ID) const override; 398 399 static bool classof(const MemRegion *R) { 400 Kind k = R->getKind(); 401 return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES; 402 } 403}; 404 405class StackLocalsSpaceRegion : public StackSpaceRegion { 406 friend class MemRegionManager; 407 408 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 409 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 410 411public: 412 void dumpToStream(raw_ostream &os) const override; 413 414 static bool classof(const MemRegion *R) { 415 return R->getKind() == StackLocalsSpaceRegionKind; 416 } 417}; 418 419class StackArgumentsSpaceRegion : public StackSpaceRegion { 420private: 421 friend class MemRegionManager; 422 423 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 424 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 425 426public: 427 void dumpToStream(raw_ostream &os) const override; 428 429 static bool classof(const MemRegion *R) { 430 return R->getKind() == StackArgumentsSpaceRegionKind; 431 } 432}; 433 434/// SubRegion - A region that subsets another larger region. Most regions 435/// are subclasses of SubRegion. 436class SubRegion : public MemRegion { 437 virtual void anchor(); 438 439protected: 440 const MemRegion* superRegion; 441 442 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) { 443 assert(classof(this)); 444 assert(sReg); 445 } 446 447public: 448 const MemRegion* getSuperRegion() const { 449 return superRegion; 450 } 451 452 /// getExtent - Returns the size of the region in bytes. 453 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { 454 return UnknownVal(); 455 } 456 457 MemRegionManager* getMemRegionManager() const override; 458 459 bool isSubRegionOf(const MemRegion* R) const override; 460 461 static bool classof(const MemRegion* R) { 462 return R->getKind() > END_MEMSPACES; 463 } 464}; 465 466//===----------------------------------------------------------------------===// 467// MemRegion subclasses. 468//===----------------------------------------------------------------------===// 469 470/// AllocaRegion - A region that represents an untyped blob of bytes created 471/// by a call to 'alloca'. 472class AllocaRegion : public SubRegion { 473 friend class MemRegionManager; 474 475 // Block counter. Used to distinguish different pieces of memory allocated by 476 // alloca at the same call site. 477 unsigned Cnt; 478 479 const Expr *Ex; 480 481 AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion) 482 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) { 483 assert(Ex); 484 } 485 486 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 487 unsigned Cnt, const MemRegion *superRegion); 488 489public: 490 const Expr *getExpr() const { return Ex; } 491 492 bool isBoundable() const override { return true; } 493 494 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; 495 496 void Profile(llvm::FoldingSetNodeID& ID) const override; 497 498 void dumpToStream(raw_ostream &os) const override; 499 500 static bool classof(const MemRegion* R) { 501 return R->getKind() == AllocaRegionKind; 502 } 503}; 504 505/// TypedRegion - An abstract class representing regions that are typed. 506class TypedRegion : public SubRegion { 507 void anchor() override; 508 509protected: 510 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) { 511 assert(classof(this)); 512 } 513 514public: 515 virtual QualType getLocationType() const = 0; 516 517 QualType getDesugaredLocationType(ASTContext &Context) const { 518 return getLocationType().getDesugaredType(Context); 519 } 520 521 bool isBoundable() const override { return true; } 522 523 static bool classof(const MemRegion* R) { 524 unsigned k = R->getKind(); 525 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS; 526 } 527}; 528 529/// TypedValueRegion - An abstract class representing regions having a typed value. 530class TypedValueRegion : public TypedRegion { 531 void anchor() override; 532 533protected: 534 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) { 535 assert(classof(this)); 536 } 537 538public: 539 virtual QualType getValueType() const = 0; 540 541 QualType getLocationType() const override { 542 // FIXME: We can possibly optimize this later to cache this value. 543 QualType T = getValueType(); 544 ASTContext &ctx = getContext(); 545 if (T->getAs<ObjCObjectType>()) 546 return ctx.getObjCObjectPointerType(T); 547 return ctx.getPointerType(getValueType()); 548 } 549 550 QualType getDesugaredValueType(ASTContext &Context) const { 551 QualType T = getValueType(); 552 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 553 } 554 555 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; 556 557 static bool classof(const MemRegion* R) { 558 unsigned k = R->getKind(); 559 return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 560 } 561}; 562 563class CodeTextRegion : public TypedRegion { 564 void anchor() override; 565 566protected: 567 CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) { 568 assert(classof(this)); 569 } 570 571public: 572 bool isBoundable() const override { return false; } 573 574 static bool classof(const MemRegion* R) { 575 Kind k = R->getKind(); 576 return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS; 577 } 578}; 579 580/// FunctionCodeRegion - A region that represents code texts of function. 581class FunctionCodeRegion : public CodeTextRegion { 582 friend class MemRegionManager; 583 584 const NamedDecl *FD; 585 586 FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg) 587 : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) { 588 assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); 589 } 590 591 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, 592 const MemRegion*); 593 594public: 595 QualType getLocationType() const override { 596 const ASTContext &Ctx = getContext(); 597 if (const auto *D = dyn_cast<FunctionDecl>(FD)) { 598 return Ctx.getPointerType(D->getType()); 599 } 600 601 assert(isa<ObjCMethodDecl>(FD)); 602 assert(false && "Getting the type of ObjCMethod is not supported yet"); 603 604 // TODO: We might want to return a different type here (ex: id (*ty)(...)) 605 // depending on how it is used. 606 return {}; 607 } 608 609 const NamedDecl *getDecl() const { 610 return FD; 611 } 612 613 void dumpToStream(raw_ostream &os) const override; 614 615 void Profile(llvm::FoldingSetNodeID& ID) const override; 616 617 static bool classof(const MemRegion* R) { 618 return R->getKind() == FunctionCodeRegionKind; 619 } 620}; 621 622/// BlockCodeRegion - A region that represents code texts of blocks (closures). 623/// Blocks are represented with two kinds of regions. BlockCodeRegions 624/// represent the "code", while BlockDataRegions represent instances of blocks, 625/// which correspond to "code+data". The distinction is important, because 626/// like a closure a block captures the values of externally referenced 627/// variables. 628class BlockCodeRegion : public CodeTextRegion { 629 friend class MemRegionManager; 630 631 const BlockDecl *BD; 632 AnalysisDeclContext *AC; 633 CanQualType locTy; 634 635 BlockCodeRegion(const BlockDecl *bd, CanQualType lTy, 636 AnalysisDeclContext *ac, const CodeSpaceRegion* sreg) 637 : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) { 638 assert(bd); 639 assert(ac); 640 assert(lTy->getTypePtr()->isBlockPointerType()); 641 } 642 643 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 644 CanQualType, const AnalysisDeclContext*, 645 const MemRegion*); 646 647public: 648 QualType getLocationType() const override { 649 return locTy; 650 } 651 652 const BlockDecl *getDecl() const { 653 return BD; 654 } 655 656 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 657 658 void dumpToStream(raw_ostream &os) const override; 659 660 void Profile(llvm::FoldingSetNodeID& ID) const override; 661 662 static bool classof(const MemRegion* R) { 663 return R->getKind() == BlockCodeRegionKind; 664 } 665}; 666 667/// BlockDataRegion - A region that represents a block instance. 668/// Blocks are represented with two kinds of regions. BlockCodeRegions 669/// represent the "code", while BlockDataRegions represent instances of blocks, 670/// which correspond to "code+data". The distinction is important, because 671/// like a closure a block captures the values of externally referenced 672/// variables. 673class BlockDataRegion : public TypedRegion { 674 friend class MemRegionManager; 675 676 const BlockCodeRegion *BC; 677 const LocationContext *LC; // Can be null 678 unsigned BlockCount; 679 void *ReferencedVars = nullptr; 680 void *OriginalVars = nullptr; 681 682 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, 683 unsigned count, const MemSpaceRegion *sreg) 684 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 685 BlockCount(count) { 686 assert(bc); 687 assert(lc); 688 assert(isa<GlobalImmutableSpaceRegion>(sreg) || 689 isa<StackLocalsSpaceRegion>(sreg) || 690 isa<UnknownSpaceRegion>(sreg)); 691 } 692 693 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *, 694 const LocationContext *, unsigned, 695 const MemRegion *); 696 697public: 698 const BlockCodeRegion *getCodeRegion() const { return BC; } 699 700 const BlockDecl *getDecl() const { return BC->getDecl(); } 701 702 QualType getLocationType() const override { return BC->getLocationType(); } 703 704 class referenced_vars_iterator { 705 const MemRegion * const *R; 706 const MemRegion * const *OriginalR; 707 708 public: 709 explicit referenced_vars_iterator(const MemRegion * const *r, 710 const MemRegion * const *originalR) 711 : R(r), OriginalR(originalR) {} 712 713 const VarRegion *getCapturedRegion() const { 714 return cast<VarRegion>(*R); 715 } 716 717 const VarRegion *getOriginalRegion() const { 718 return cast<VarRegion>(*OriginalR); 719 } 720 721 bool operator==(const referenced_vars_iterator &I) const { 722 assert((R == nullptr) == (I.R == nullptr)); 723 return I.R == R; 724 } 725 726 bool operator!=(const referenced_vars_iterator &I) const { 727 assert((R == nullptr) == (I.R == nullptr)); 728 return I.R != R; 729 } 730 731 referenced_vars_iterator &operator++() { 732 ++R; 733 ++OriginalR; 734 return *this; 735 } 736 }; 737 738 /// Return the original region for a captured region, if 739 /// one exists. 740 const VarRegion *getOriginalRegion(const VarRegion *VR) const; 741 742 referenced_vars_iterator referenced_vars_begin() const; 743 referenced_vars_iterator referenced_vars_end() const; 744 745 void dumpToStream(raw_ostream &os) const override; 746 747 void Profile(llvm::FoldingSetNodeID& ID) const override; 748 749 static bool classof(const MemRegion* R) { 750 return R->getKind() == BlockDataRegionKind; 751 } 752 753private: 754 void LazyInitializeReferencedVars(); 755 std::pair<const VarRegion *, const VarRegion *> 756 getCaptureRegions(const VarDecl *VD); 757}; 758 759/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 760/// classes, SymbolicRegion represents a region that serves as an alias for 761/// either a real region, a NULL pointer, etc. It essentially is used to 762/// map the concept of symbolic values into the domain of regions. Symbolic 763/// regions do not need to be typed. 764class SymbolicRegion : public SubRegion { 765 friend class MemRegionManager; 766 767 const SymbolRef sym; 768 769 SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg) 770 : SubRegion(sreg, SymbolicRegionKind), sym(s) { 771 // Because pointer arithmetic is represented by ElementRegion layers, 772 // the base symbol here should not contain any arithmetic. 773 assert(s && isa<SymbolData>(s)); 774 assert(s->getType()->isAnyPointerType() || 775 s->getType()->isReferenceType() || 776 s->getType()->isBlockPointerType()); 777 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg)); 778 } 779 780public: 781 SymbolRef getSymbol() const { return sym; } 782 783 bool isBoundable() const override { return true; } 784 785 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; 786 787 void Profile(llvm::FoldingSetNodeID& ID) const override; 788 789 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 790 SymbolRef sym, 791 const MemRegion* superRegion); 792 793 void dumpToStream(raw_ostream &os) const override; 794 795 static bool classof(const MemRegion* R) { 796 return R->getKind() == SymbolicRegionKind; 797 } 798}; 799 800/// StringRegion - Region associated with a StringLiteral. 801class StringRegion : public TypedValueRegion { 802 friend class MemRegionManager; 803 804 const StringLiteral *Str; 805 806 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg) 807 : TypedValueRegion(sreg, StringRegionKind), Str(str) { 808 assert(str); 809 } 810 811 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 812 const StringLiteral *Str, 813 const MemRegion *superRegion); 814 815public: 816 const StringLiteral *getStringLiteral() const { return Str; } 817 818 QualType getValueType() const override { return Str->getType(); } 819 820 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; 821 822 bool isBoundable() const override { return false; } 823 824 void Profile(llvm::FoldingSetNodeID& ID) const override { 825 ProfileRegion(ID, Str, superRegion); 826 } 827 828 void dumpToStream(raw_ostream &os) const override; 829 830 static bool classof(const MemRegion* R) { 831 return R->getKind() == StringRegionKind; 832 } 833}; 834 835/// The region associated with an ObjCStringLiteral. 836class ObjCStringRegion : public TypedValueRegion { 837 friend class MemRegionManager; 838 839 const ObjCStringLiteral *Str; 840 841 ObjCStringRegion(const ObjCStringLiteral *str, 842 const GlobalInternalSpaceRegion *sreg) 843 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) { 844 assert(str); 845 } 846 847 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 848 const ObjCStringLiteral *Str, 849 const MemRegion *superRegion); 850 851public: 852 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; } 853 854 QualType getValueType() const override { return Str->getType(); } 855 856 bool isBoundable() const override { return false; } 857 858 void Profile(llvm::FoldingSetNodeID& ID) const override { 859 ProfileRegion(ID, Str, superRegion); 860 } 861 862 void dumpToStream(raw_ostream &os) const override; 863 864 static bool classof(const MemRegion* R) { 865 return R->getKind() == ObjCStringRegionKind; 866 } 867}; 868 869/// CompoundLiteralRegion - A memory region representing a compound literal. 870/// Compound literals are essentially temporaries that are stack allocated 871/// or in the global constant pool. 872class CompoundLiteralRegion : public TypedValueRegion { 873 friend class MemRegionManager; 874 875 const CompoundLiteralExpr *CL; 876 877 CompoundLiteralRegion(const CompoundLiteralExpr *cl, 878 const MemSpaceRegion *sReg) 879 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) { 880 assert(cl); 881 assert(isa<GlobalInternalSpaceRegion>(sReg) || 882 isa<StackLocalsSpaceRegion>(sReg)); 883 } 884 885 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 886 const CompoundLiteralExpr *CL, 887 const MemRegion* superRegion); 888 889public: 890 QualType getValueType() const override { return CL->getType(); } 891 892 bool isBoundable() const override { return !CL->isFileScope(); } 893 894 void Profile(llvm::FoldingSetNodeID& ID) const override; 895 896 void dumpToStream(raw_ostream &os) const override; 897 898 const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 899 900 static bool classof(const MemRegion* R) { 901 return R->getKind() == CompoundLiteralRegionKind; 902 } 903}; 904 905class DeclRegion : public TypedValueRegion { 906protected: 907 const ValueDecl *D; 908 909 DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k) 910 : TypedValueRegion(sReg, k), D(d) { 911 assert(classof(this)); 912 assert(d && d->isCanonicalDecl()); 913 } 914 915 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 916 const MemRegion* superRegion, Kind k); 917 918public: 919 const ValueDecl *getDecl() const { return D; } 920 void Profile(llvm::FoldingSetNodeID& ID) const override; 921 922 static bool classof(const MemRegion* R) { 923 unsigned k = R->getKind(); 924 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS; 925 } 926}; 927 928class VarRegion : public DeclRegion { 929 friend class MemRegionManager; 930 931 // Constructors and private methods. 932 VarRegion(const VarDecl *vd, const MemRegion *sReg) 933 : DeclRegion(vd, sReg, VarRegionKind) { 934 // VarRegion appears in unknown space when it's a block variable as seen 935 // from a block using it, when this block is analyzed at top-level. 936 // Other block variables appear within block data regions, 937 // which, unlike everything else on this list, are not memory spaces. 938 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || 939 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)); 940 } 941 942 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, 943 const MemRegion *superRegion) { 944 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 945 } 946 947public: 948 void Profile(llvm::FoldingSetNodeID& ID) const override; 949 950 const VarDecl *getDecl() const { return cast<VarDecl>(D); } 951 952 const StackFrameContext *getStackFrame() const; 953 954 QualType getValueType() const override { 955 // FIXME: We can cache this if needed. 956 return getDecl()->getType(); 957 } 958 959 void dumpToStream(raw_ostream &os) const override; 960 961 bool canPrintPrettyAsExpr() const override; 962 963 void printPrettyAsExpr(raw_ostream &os) const override; 964 965 static bool classof(const MemRegion* R) { 966 return R->getKind() == VarRegionKind; 967 } 968}; 969 970/// CXXThisRegion - Represents the region for the implicit 'this' parameter 971/// in a call to a C++ method. This region doesn't represent the object 972/// referred to by 'this', but rather 'this' itself. 973class CXXThisRegion : public TypedValueRegion { 974 friend class MemRegionManager; 975 976 CXXThisRegion(const PointerType *thisPointerTy, 977 const StackArgumentsSpaceRegion *sReg) 978 : TypedValueRegion(sReg, CXXThisRegionKind), 979 ThisPointerTy(thisPointerTy) { 980 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && 981 "Invalid region type!"); 982 } 983 984 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 985 const PointerType *PT, 986 const MemRegion *sReg); 987 988public: 989 void Profile(llvm::FoldingSetNodeID &ID) const override; 990 991 QualType getValueType() const override { 992 return QualType(ThisPointerTy, 0); 993 } 994 995 void dumpToStream(raw_ostream &os) const override; 996 997 static bool classof(const MemRegion* R) { 998 return R->getKind() == CXXThisRegionKind; 999 } 1000 1001private: 1002 const PointerType *ThisPointerTy; 1003}; 1004 1005class FieldRegion : public DeclRegion { 1006 friend class MemRegionManager; 1007 1008 FieldRegion(const FieldDecl *fd, const SubRegion* sReg) 1009 : DeclRegion(fd, sReg, FieldRegionKind) {} 1010 1011 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, 1012 const MemRegion* superRegion) { 1013 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 1014 } 1015 1016public: 1017 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } 1018 1019 QualType getValueType() const override { 1020 // FIXME: We can cache this if needed. 1021 return getDecl()->getType(); 1022 } 1023 1024 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; 1025 1026 void dumpToStream(raw_ostream &os) const override; 1027 1028 bool canPrintPretty() const override; 1029 void printPretty(raw_ostream &os) const override; 1030 bool canPrintPrettyAsExpr() const override; 1031 void printPrettyAsExpr(raw_ostream &os) const override; 1032 1033 static bool classof(const MemRegion* R) { 1034 return R->getKind() == FieldRegionKind; 1035 } 1036}; 1037 1038class ObjCIvarRegion : public DeclRegion { 1039 friend class MemRegionManager; 1040 1041 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg); 1042 1043 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 1044 const MemRegion* superRegion); 1045 1046public: 1047 const ObjCIvarDecl *getDecl() const; 1048 QualType getValueType() const override; 1049 1050 bool canPrintPrettyAsExpr() const override; 1051 void printPrettyAsExpr(raw_ostream &os) const override; 1052 1053 void dumpToStream(raw_ostream &os) const override; 1054 1055 static bool classof(const MemRegion* R) { 1056 return R->getKind() == ObjCIvarRegionKind; 1057 } 1058}; 1059 1060//===----------------------------------------------------------------------===// 1061// Auxiliary data classes for use with MemRegions. 1062//===----------------------------------------------------------------------===// 1063 1064class RegionRawOffset { 1065 friend class ElementRegion; 1066 1067 const MemRegion *Region; 1068 CharUnits Offset; 1069 1070 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 1071 : Region(reg), Offset(offset) {} 1072 1073public: 1074 // FIXME: Eventually support symbolic offsets. 1075 CharUnits getOffset() const { return Offset; } 1076 const MemRegion *getRegion() const { return Region; } 1077 1078 void dumpToStream(raw_ostream &os) const; 1079 void dump() const; 1080}; 1081 1082/// ElementRegion is used to represent both array elements and casts. 1083class ElementRegion : public TypedValueRegion { 1084 friend class MemRegionManager; 1085 1086 QualType ElementType; 1087 NonLoc Index; 1088 1089 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg) 1090 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType), 1091 Index(Idx) { 1092 assert((!Idx.getAs<nonloc::ConcreteInt>() || 1093 Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && 1094 "The index must be signed"); 1095 assert(!elementType.isNull() && !elementType->isVoidType() && 1096 "Invalid region type!"); 1097 } 1098 1099 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 1100 SVal Idx, const MemRegion* superRegion); 1101 1102public: 1103 NonLoc getIndex() const { return Index; } 1104 1105 QualType getValueType() const override { return ElementType; } 1106 1107 QualType getElementType() const { return ElementType; } 1108 1109 /// Compute the offset within the array. The array might also be a subobject. 1110 RegionRawOffset getAsArrayOffset() const; 1111 1112 void dumpToStream(raw_ostream &os) const override; 1113 1114 void Profile(llvm::FoldingSetNodeID& ID) const override; 1115 1116 static bool classof(const MemRegion* R) { 1117 return R->getKind() == ElementRegionKind; 1118 } 1119}; 1120 1121// C++ temporary object associated with an expression. 1122class CXXTempObjectRegion : public TypedValueRegion { 1123 friend class MemRegionManager; 1124 1125 Expr const *Ex; 1126 1127 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg) 1128 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) { 1129 assert(E); 1130 assert(isa<StackLocalsSpaceRegion>(sReg) || 1131 isa<GlobalInternalSpaceRegion>(sReg)); 1132 } 1133 1134 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1135 Expr const *E, const MemRegion *sReg); 1136 1137public: 1138 const Expr *getExpr() const { return Ex; } 1139 1140 QualType getValueType() const override { return Ex->getType(); } 1141 1142 void dumpToStream(raw_ostream &os) const override; 1143 1144 void Profile(llvm::FoldingSetNodeID &ID) const override; 1145 1146 static bool classof(const MemRegion* R) { 1147 return R->getKind() == CXXTempObjectRegionKind; 1148 } 1149}; 1150 1151// CXXBaseObjectRegion represents a base object within a C++ object. It is 1152// identified by the base class declaration and the region of its parent object. 1153class CXXBaseObjectRegion : public TypedValueRegion { 1154 friend class MemRegionManager; 1155 1156 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data; 1157 1158 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual, 1159 const SubRegion *SReg) 1160 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) { 1161 assert(RD); 1162 } 1163 1164 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1165 bool IsVirtual, const MemRegion *SReg); 1166 1167public: 1168 const CXXRecordDecl *getDecl() const { return Data.getPointer(); } 1169 bool isVirtual() const { return Data.getInt(); } 1170 1171 QualType getValueType() const override; 1172 1173 void dumpToStream(raw_ostream &os) const override; 1174 1175 void Profile(llvm::FoldingSetNodeID &ID) const override; 1176 1177 bool canPrintPrettyAsExpr() const override; 1178 1179 void printPrettyAsExpr(raw_ostream &os) const override; 1180 1181 static bool classof(const MemRegion *region) { 1182 return region->getKind() == CXXBaseObjectRegionKind; 1183 } 1184}; 1185 1186// CXXDerivedObjectRegion represents a derived-class object that surrounds 1187// a C++ object. It is identified by the derived class declaration and the 1188// region of its parent object. It is a bit counter-intuitive (but not otherwise 1189// unseen) that this region represents a larger segment of memory that its 1190// super-region. 1191class CXXDerivedObjectRegion : public TypedValueRegion { 1192 friend class MemRegionManager; 1193 1194 const CXXRecordDecl *DerivedD; 1195 1196 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg) 1197 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) { 1198 assert(DerivedD); 1199 // In case of a concrete region, it should always be possible to model 1200 // the base-to-derived cast by undoing a previous derived-to-base cast, 1201 // otherwise the cast is most likely ill-formed. 1202 assert(SReg->getSymbolicBase() && 1203 "Should have unwrapped a base region instead!"); 1204 } 1205 1206 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1207 const MemRegion *SReg); 1208 1209public: 1210 const CXXRecordDecl *getDecl() const { return DerivedD; } 1211 1212 QualType getValueType() const override; 1213 1214 void dumpToStream(raw_ostream &os) const override; 1215 1216 void Profile(llvm::FoldingSetNodeID &ID) const override; 1217 1218 bool canPrintPrettyAsExpr() const override; 1219 1220 void printPrettyAsExpr(raw_ostream &os) const override; 1221 1222 static bool classof(const MemRegion *region) { 1223 return region->getKind() == CXXDerivedObjectRegionKind; 1224 } 1225}; 1226 1227template<typename RegionTy> 1228const RegionTy* MemRegion::getAs() const { 1229 if (const auto *RT = dyn_cast<RegionTy>(this)) 1230 return RT; 1231 1232 return nullptr; 1233} 1234 1235template<typename RegionTy> 1236const RegionTy* MemRegion::castAs() const { 1237 return cast<RegionTy>(this); 1238} 1239 1240//===----------------------------------------------------------------------===// 1241// MemRegionManager - Factory object for creating regions. 1242//===----------------------------------------------------------------------===// 1243 1244class MemRegionManager { 1245 ASTContext &C; 1246 llvm::BumpPtrAllocator& A; 1247 llvm::FoldingSet<MemRegion> Regions; 1248 1249 GlobalInternalSpaceRegion *InternalGlobals = nullptr; 1250 GlobalSystemSpaceRegion *SystemGlobals = nullptr; 1251 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr; 1252 1253 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 1254 StackLocalsSpaceRegions; 1255 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 1256 StackArgumentsSpaceRegions; 1257 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 1258 StaticsGlobalSpaceRegions; 1259 1260 HeapSpaceRegion *heap = nullptr; 1261 UnknownSpaceRegion *unknown = nullptr; 1262 CodeSpaceRegion *code = nullptr; 1263 1264public: 1265 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {} 1266 ~MemRegionManager(); 1267 1268 ASTContext &getContext() { return C; } 1269 1270 llvm::BumpPtrAllocator &getAllocator() { return A; } 1271 1272 /// getStackLocalsRegion - Retrieve the memory region associated with the 1273 /// specified stack frame. 1274 const StackLocalsSpaceRegion * 1275 getStackLocalsRegion(const StackFrameContext *STC); 1276 1277 /// getStackArgumentsRegion - Retrieve the memory region associated with 1278 /// function/method arguments of the specified stack frame. 1279 const StackArgumentsSpaceRegion * 1280 getStackArgumentsRegion(const StackFrameContext *STC); 1281 1282 /// getGlobalsRegion - Retrieve the memory region associated with 1283 /// global variables. 1284 const GlobalsSpaceRegion *getGlobalsRegion( 1285 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1286 const CodeTextRegion *R = nullptr); 1287 1288 /// getHeapRegion - Retrieve the memory region associated with the 1289 /// generic "heap". 1290 const HeapSpaceRegion *getHeapRegion(); 1291 1292 /// getUnknownRegion - Retrieve the memory region associated with unknown 1293 /// memory space. 1294 const UnknownSpaceRegion *getUnknownRegion(); 1295 1296 const CodeSpaceRegion *getCodeRegion(); 1297 1298 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1299 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1300 const LocationContext *LC); 1301 1302 /// getCompoundLiteralRegion - Retrieve the region associated with a 1303 /// given CompoundLiteral. 1304 const CompoundLiteralRegion* 1305 getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1306 const LocationContext *LC); 1307 1308 /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1309 /// parameter 'this'. 1310 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1311 const LocationContext *LC); 1312 1313 /// Retrieve or create a "symbolic" memory region. 1314 const SymbolicRegion* getSymbolicRegion(SymbolRef Sym); 1315 1316 /// Return a unique symbolic region belonging to heap memory space. 1317 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); 1318 1319 const StringRegion *getStringRegion(const StringLiteral *Str); 1320 1321 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1322 1323 /// getVarRegion - Retrieve or create the memory region associated with 1324 /// a specified VarDecl and LocationContext. 1325 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 1326 1327 /// getVarRegion - Retrieve or create the memory region associated with 1328 /// a specified VarDecl and super region. 1329 const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR); 1330 1331 /// getElementRegion - Retrieve the memory region associated with the 1332 /// associated element type, index, and super region. 1333 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1334 const SubRegion *superRegion, 1335 ASTContext &Ctx); 1336 1337 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1338 const SubRegion *superRegion) { 1339 return getElementRegion(ER->getElementType(), ER->getIndex(), 1340 superRegion, ER->getContext()); 1341 } 1342 1343 /// getFieldRegion - Retrieve or create the memory region associated with 1344 /// a specified FieldDecl. 'superRegion' corresponds to the containing 1345 /// memory region (which typically represents the memory representing 1346 /// a structure or class). 1347 const FieldRegion *getFieldRegion(const FieldDecl *fd, 1348 const SubRegion* superRegion); 1349 1350 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1351 const SubRegion *superRegion) { 1352 return getFieldRegion(FR->getDecl(), superRegion); 1353 } 1354 1355 /// getObjCIvarRegion - Retrieve or create the memory region associated with 1356 /// a specified Objective-c instance variable. 'superRegion' corresponds 1357 /// to the containing region (which typically represents the Objective-C 1358 /// object). 1359 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1360 const SubRegion* superRegion); 1361 1362 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1363 LocationContext const *LC); 1364 1365 /// Create a CXXBaseObjectRegion with the given base class for region 1366 /// \p Super. 1367 /// 1368 /// The type of \p Super is assumed be a class deriving from \p BaseClass. 1369 const CXXBaseObjectRegion * 1370 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, 1371 bool IsVirtual); 1372 1373 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1374 /// super region. 1375 const CXXBaseObjectRegion * 1376 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1377 const SubRegion *superRegion) { 1378 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, 1379 baseReg->isVirtual()); 1380 } 1381 1382 /// Create a CXXDerivedObjectRegion with the given derived class for region 1383 /// \p Super. This should not be used for casting an existing 1384 /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion 1385 /// should be removed. 1386 const CXXDerivedObjectRegion * 1387 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, 1388 const SubRegion *Super); 1389 1390 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD); 1391 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD, 1392 CanQualType locTy, 1393 AnalysisDeclContext *AC); 1394 1395 /// getBlockDataRegion - Get the memory region associated with an instance 1396 /// of a block. Unlike many other MemRegions, the LocationContext* 1397 /// argument is allowed to be NULL for cases where we have no known 1398 /// context. 1399 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc, 1400 const LocationContext *lc, 1401 unsigned blockCount); 1402 1403 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended 1404 /// by static references. This differs from getCXXTempObjectRegion in the 1405 /// super-region used. 1406 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); 1407 1408private: 1409 template <typename RegionTy, typename SuperTy, 1410 typename Arg1Ty> 1411 RegionTy* getSubRegion(const Arg1Ty arg1, 1412 const SuperTy* superRegion); 1413 1414 template <typename RegionTy, typename SuperTy, 1415 typename Arg1Ty, typename Arg2Ty> 1416 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, 1417 const SuperTy* superRegion); 1418 1419 template <typename RegionTy, typename SuperTy, 1420 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty> 1421 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, 1422 const Arg3Ty arg3, 1423 const SuperTy* superRegion); 1424 1425 template <typename REG> 1426 const REG* LazyAllocate(REG*& region); 1427 1428 template <typename REG, typename ARG> 1429 const REG* LazyAllocate(REG*& region, ARG a); 1430}; 1431 1432//===----------------------------------------------------------------------===// 1433// Out-of-line member definitions. 1434//===----------------------------------------------------------------------===// 1435 1436inline ASTContext &MemRegion::getContext() const { 1437 return getMemRegionManager()->getContext(); 1438} 1439 1440//===----------------------------------------------------------------------===// 1441// Means for storing region/symbol handling traits. 1442//===----------------------------------------------------------------------===// 1443 1444/// Information about invalidation for a particular region/symbol. 1445class RegionAndSymbolInvalidationTraits { 1446 using StorageTypeForKinds = unsigned char; 1447 1448 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap; 1449 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap; 1450 1451 using const_region_iterator = 1452 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator; 1453 using const_symbol_iterator = 1454 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator; 1455 1456public: 1457 /// Describes different invalidation traits. 1458 enum InvalidationKinds { 1459 /// Tells that a region's contents is not changed. 1460 TK_PreserveContents = 0x1, 1461 1462 /// Suppress pointer-escaping of a region. 1463 TK_SuppressEscape = 0x2, 1464 1465 // Do not invalidate super region. 1466 TK_DoNotInvalidateSuperRegion = 0x4, 1467 1468 /// When applied to a MemSpaceRegion, indicates the entire memory space 1469 /// should be invalidated. 1470 TK_EntireMemSpace = 0x8 1471 1472 // Do not forget to extend StorageTypeForKinds if number of traits exceed 1473 // the number of bits StorageTypeForKinds can store. 1474 }; 1475 1476 void setTrait(SymbolRef Sym, InvalidationKinds IK); 1477 void setTrait(const MemRegion *MR, InvalidationKinds IK); 1478 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const; 1479 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const; 1480}; 1481 1482//===----------------------------------------------------------------------===// 1483// Pretty-printing regions. 1484//===----------------------------------------------------------------------===// 1485inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) { 1486 R->dumpToStream(os); 1487 return os; 1488} 1489 1490} // namespace ento 1491 1492} // namespace clang 1493 1494#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 1495