xref: /freebsd-src/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/MemRegion.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MemRegion.cpp - Abstract memory regions for static analysis --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines MemRegion and its subclasses.  MemRegion defines a
100b57cec5SDimitry Andric //  partially-typed abstraction of memory useful for path-sensitive dataflow
110b57cec5SDimitry Andric //  analyses.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
170b57cec5SDimitry Andric #include "clang/AST/Attr.h"
180b57cec5SDimitry Andric #include "clang/AST/CharUnits.h"
190b57cec5SDimitry Andric #include "clang/AST/Decl.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
220b57cec5SDimitry Andric #include "clang/AST/Expr.h"
230b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
240b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
250b57cec5SDimitry Andric #include "clang/AST/Type.h"
260b57cec5SDimitry Andric #include "clang/Analysis/AnalysisDeclContext.h"
270b57cec5SDimitry Andric #include "clang/Analysis/Support/BumpVector.h"
280b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
290b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
300b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
31349cc55cSDimitry Andric #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
32fe6060f1SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
330b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
340b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
350b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
360b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
370b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
380b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h"
390b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
400b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
410b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
4206c3fb27SDimitry Andric #include "llvm/ADT/iterator_range.h"
430b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
440b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
450b57cec5SDimitry Andric #include "llvm/Support/CheckedArithmetic.h"
460b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
470b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
480b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
490b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
500b57cec5SDimitry Andric #include <cassert>
510b57cec5SDimitry Andric #include <cstdint>
520b57cec5SDimitry Andric #include <functional>
530b57cec5SDimitry Andric #include <iterator>
54bdd1243dSDimitry Andric #include <optional>
550b57cec5SDimitry Andric #include <string>
560b57cec5SDimitry Andric #include <tuple>
570b57cec5SDimitry Andric #include <utility>
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric using namespace clang;
600b57cec5SDimitry Andric using namespace ento;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric #define DEBUG_TYPE "MemRegion"
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
650b57cec5SDimitry Andric // MemRegion Construction.
660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric template <typename RegionTy, typename SuperTy, typename Arg1Ty>
690b57cec5SDimitry Andric RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
700b57cec5SDimitry Andric                                          const SuperTy *superRegion) {
710b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
720b57cec5SDimitry Andric   RegionTy::ProfileRegion(ID, arg1, superRegion);
730b57cec5SDimitry Andric   void *InsertPos;
740b57cec5SDimitry Andric   auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   if (!R) {
7706c3fb27SDimitry Andric     R = new (A) RegionTy(arg1, superRegion);
780b57cec5SDimitry Andric     Regions.InsertNode(R, InsertPos);
790b57cec5SDimitry Andric   }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   return R;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
850b57cec5SDimitry Andric RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
860b57cec5SDimitry Andric                                          const SuperTy *superRegion) {
870b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
880b57cec5SDimitry Andric   RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
890b57cec5SDimitry Andric   void *InsertPos;
900b57cec5SDimitry Andric   auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   if (!R) {
9306c3fb27SDimitry Andric     R = new (A) RegionTy(arg1, arg2, superRegion);
940b57cec5SDimitry Andric     Regions.InsertNode(R, InsertPos);
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   return R;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric template <typename RegionTy, typename SuperTy,
1010b57cec5SDimitry Andric           typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1020b57cec5SDimitry Andric RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1030b57cec5SDimitry Andric                                          const Arg3Ty arg3,
1040b57cec5SDimitry Andric                                          const SuperTy *superRegion) {
1050b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
1060b57cec5SDimitry Andric   RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
1070b57cec5SDimitry Andric   void *InsertPos;
1080b57cec5SDimitry Andric   auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   if (!R) {
11106c3fb27SDimitry Andric     R = new (A) RegionTy(arg1, arg2, arg3, superRegion);
1120b57cec5SDimitry Andric     Regions.InsertNode(R, InsertPos);
1130b57cec5SDimitry Andric   }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   return R;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1190b57cec5SDimitry Andric // Object destruction.
1200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric MemRegion::~MemRegion() = default;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric // All regions and their data are BumpPtrAllocated.  No need to call their
1250b57cec5SDimitry Andric // destructors.
1260b57cec5SDimitry Andric MemRegionManager::~MemRegionManager() = default;
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1290b57cec5SDimitry Andric // Basic methods.
1300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric bool SubRegion::isSubRegionOf(const MemRegion* R) const {
1330b57cec5SDimitry Andric   const MemRegion* r = this;
1340b57cec5SDimitry Andric   do {
1350b57cec5SDimitry Andric     if (r == R)
1360b57cec5SDimitry Andric       return true;
1370b57cec5SDimitry Andric     if (const auto *sr = dyn_cast<SubRegion>(r))
1380b57cec5SDimitry Andric       r = sr->getSuperRegion();
1390b57cec5SDimitry Andric     else
1400b57cec5SDimitry Andric       break;
1410b57cec5SDimitry Andric   } while (r != nullptr);
1420b57cec5SDimitry Andric   return false;
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
1455ffd83dbSDimitry Andric MemRegionManager &SubRegion::getMemRegionManager() const {
1460b57cec5SDimitry Andric   const SubRegion* r = this;
1470b57cec5SDimitry Andric   do {
1480b57cec5SDimitry Andric     const MemRegion *superRegion = r->getSuperRegion();
1490b57cec5SDimitry Andric     if (const auto *sr = dyn_cast<SubRegion>(superRegion)) {
1500b57cec5SDimitry Andric       r = sr;
1510b57cec5SDimitry Andric       continue;
1520b57cec5SDimitry Andric     }
1530b57cec5SDimitry Andric     return superRegion->getMemRegionManager();
1540b57cec5SDimitry Andric   } while (true);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric const StackFrameContext *VarRegion::getStackFrame() const {
1580b57cec5SDimitry Andric   const auto *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
1590b57cec5SDimitry Andric   return SSR ? SSR->getStackFrame() : nullptr;
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
16206c3fb27SDimitry Andric const StackFrameContext *
16306c3fb27SDimitry Andric CXXLifetimeExtendedObjectRegion::getStackFrame() const {
16406c3fb27SDimitry Andric   const auto *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
16506c3fb27SDimitry Andric   return SSR ? SSR->getStackFrame() : nullptr;
16606c3fb27SDimitry Andric }
16706c3fb27SDimitry Andric 
16806c3fb27SDimitry Andric const StackFrameContext *CXXTempObjectRegion::getStackFrame() const {
16906c3fb27SDimitry Andric   assert(isa<StackSpaceRegion>(getMemorySpace()) &&
17006c3fb27SDimitry Andric          "A temporary object can only be allocated on the stack");
17106c3fb27SDimitry Andric   return cast<StackSpaceRegion>(getMemorySpace())->getStackFrame();
17206c3fb27SDimitry Andric }
17306c3fb27SDimitry Andric 
1740b57cec5SDimitry Andric ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
17581ad6265SDimitry Andric     : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {
17681ad6265SDimitry Andric   assert(IVD);
17781ad6265SDimitry Andric }
1780b57cec5SDimitry Andric 
1795ffd83dbSDimitry Andric const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { return IVD; }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric QualType ObjCIvarRegion::getValueType() const {
1820b57cec5SDimitry Andric   return getDecl()->getType();
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric QualType CXXBaseObjectRegion::getValueType() const {
1860b57cec5SDimitry Andric   return QualType(getDecl()->getTypeForDecl(), 0);
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric QualType CXXDerivedObjectRegion::getValueType() const {
1900b57cec5SDimitry Andric   return QualType(getDecl()->getTypeForDecl(), 0);
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1935ffd83dbSDimitry Andric QualType ParamVarRegion::getValueType() const {
1945ffd83dbSDimitry Andric   assert(getDecl() &&
1955ffd83dbSDimitry Andric          "`ParamVarRegion` support functions without `Decl` not implemented"
1965ffd83dbSDimitry Andric          " yet.");
1975ffd83dbSDimitry Andric   return getDecl()->getType();
1985ffd83dbSDimitry Andric }
1995ffd83dbSDimitry Andric 
2005ffd83dbSDimitry Andric const ParmVarDecl *ParamVarRegion::getDecl() const {
2015ffd83dbSDimitry Andric   const Decl *D = getStackFrame()->getDecl();
2025ffd83dbSDimitry Andric 
2035ffd83dbSDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2045ffd83dbSDimitry Andric     assert(Index < FD->param_size());
2055ffd83dbSDimitry Andric     return FD->parameters()[Index];
2065ffd83dbSDimitry Andric   } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
2075ffd83dbSDimitry Andric     assert(Index < BD->param_size());
2085ffd83dbSDimitry Andric     return BD->parameters()[Index];
2095ffd83dbSDimitry Andric   } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
2105ffd83dbSDimitry Andric     assert(Index < MD->param_size());
2115ffd83dbSDimitry Andric     return MD->parameters()[Index];
2125ffd83dbSDimitry Andric   } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
2135ffd83dbSDimitry Andric     assert(Index < CD->param_size());
2145ffd83dbSDimitry Andric     return CD->parameters()[Index];
2155ffd83dbSDimitry Andric   } else {
2165ffd83dbSDimitry Andric     llvm_unreachable("Unexpected Decl kind!");
2175ffd83dbSDimitry Andric   }
2185ffd83dbSDimitry Andric }
2195ffd83dbSDimitry Andric 
2200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2210b57cec5SDimitry Andric // FoldingSet profiling.
2220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric void MemSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
2250b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(getKind()));
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
2290b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(getKind()));
2300b57cec5SDimitry Andric   ID.AddPointer(getStackFrame());
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
2340b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(getKind()));
2350b57cec5SDimitry Andric   ID.AddPointer(getCodeRegion());
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
2390b57cec5SDimitry Andric                                  const StringLiteral *Str,
2400b57cec5SDimitry Andric                                  const MemRegion *superRegion) {
2410b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(StringRegionKind));
2420b57cec5SDimitry Andric   ID.AddPointer(Str);
2430b57cec5SDimitry Andric   ID.AddPointer(superRegion);
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
2470b57cec5SDimitry Andric                                      const ObjCStringLiteral *Str,
2480b57cec5SDimitry Andric                                      const MemRegion *superRegion) {
2490b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(ObjCStringRegionKind));
2500b57cec5SDimitry Andric   ID.AddPointer(Str);
2510b57cec5SDimitry Andric   ID.AddPointer(superRegion);
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
2550b57cec5SDimitry Andric                                  const Expr *Ex, unsigned cnt,
2560b57cec5SDimitry Andric                                  const MemRegion *superRegion) {
2570b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
2580b57cec5SDimitry Andric   ID.AddPointer(Ex);
2590b57cec5SDimitry Andric   ID.AddInteger(cnt);
2600b57cec5SDimitry Andric   ID.AddPointer(superRegion);
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
2640b57cec5SDimitry Andric   ProfileRegion(ID, Ex, Cnt, superRegion);
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
2680b57cec5SDimitry Andric   CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
2720b57cec5SDimitry Andric                                           const CompoundLiteralExpr *CL,
2730b57cec5SDimitry Andric                                           const MemRegion* superRegion) {
2740b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
2750b57cec5SDimitry Andric   ID.AddPointer(CL);
2760b57cec5SDimitry Andric   ID.AddPointer(superRegion);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
2800b57cec5SDimitry Andric                                   const PointerType *PT,
2810b57cec5SDimitry Andric                                   const MemRegion *sRegion) {
2820b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(CXXThisRegionKind));
2830b57cec5SDimitry Andric   ID.AddPointer(PT);
2840b57cec5SDimitry Andric   ID.AddPointer(sRegion);
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
2880b57cec5SDimitry Andric   CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric 
2915ffd83dbSDimitry Andric void FieldRegion::Profile(llvm::FoldingSetNodeID &ID) const {
2925ffd83dbSDimitry Andric   ProfileRegion(ID, getDecl(), superRegion);
2935ffd83dbSDimitry Andric }
2945ffd83dbSDimitry Andric 
2950b57cec5SDimitry Andric void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
2960b57cec5SDimitry Andric                                    const ObjCIvarDecl *ivd,
2970b57cec5SDimitry Andric                                    const MemRegion* superRegion) {
2985ffd83dbSDimitry Andric   ID.AddInteger(static_cast<unsigned>(ObjCIvarRegionKind));
2995ffd83dbSDimitry Andric   ID.AddPointer(ivd);
3000b57cec5SDimitry Andric   ID.AddPointer(superRegion);
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3035ffd83dbSDimitry Andric void ObjCIvarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
3045ffd83dbSDimitry Andric   ProfileRegion(ID, getDecl(), superRegion);
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric 
3075ffd83dbSDimitry Andric void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
3085ffd83dbSDimitry Andric                                       const VarDecl *VD,
3095ffd83dbSDimitry Andric                                       const MemRegion *superRegion) {
3105ffd83dbSDimitry Andric   ID.AddInteger(static_cast<unsigned>(NonParamVarRegionKind));
3115ffd83dbSDimitry Andric   ID.AddPointer(VD);
3125ffd83dbSDimitry Andric   ID.AddPointer(superRegion);
3135ffd83dbSDimitry Andric }
3145ffd83dbSDimitry Andric 
3155ffd83dbSDimitry Andric void NonParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
3165ffd83dbSDimitry Andric   ProfileRegion(ID, getDecl(), superRegion);
3175ffd83dbSDimitry Andric }
3185ffd83dbSDimitry Andric 
3195ffd83dbSDimitry Andric void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
3205ffd83dbSDimitry Andric                                    unsigned Idx, const MemRegion *SReg) {
3215ffd83dbSDimitry Andric   ID.AddInteger(static_cast<unsigned>(ParamVarRegionKind));
3225ffd83dbSDimitry Andric   ID.AddPointer(OE);
3235ffd83dbSDimitry Andric   ID.AddInteger(Idx);
3245ffd83dbSDimitry Andric   ID.AddPointer(SReg);
3255ffd83dbSDimitry Andric }
3265ffd83dbSDimitry Andric 
3275ffd83dbSDimitry Andric void ParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
3285ffd83dbSDimitry Andric   ProfileRegion(ID, getOriginExpr(), getIndex(), superRegion);
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
3320b57cec5SDimitry Andric                                    const MemRegion *sreg) {
3330b57cec5SDimitry Andric   ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
3340b57cec5SDimitry Andric   ID.Add(sym);
3350b57cec5SDimitry Andric   ID.AddPointer(sreg);
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
3390b57cec5SDimitry Andric   SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
3430b57cec5SDimitry Andric                                   QualType ElementType, SVal Idx,
3440b57cec5SDimitry Andric                                   const MemRegion* superRegion) {
3450b57cec5SDimitry Andric   ID.AddInteger(MemRegion::ElementRegionKind);
3460b57cec5SDimitry Andric   ID.Add(ElementType);
3470b57cec5SDimitry Andric   ID.AddPointer(superRegion);
3480b57cec5SDimitry Andric   Idx.Profile(ID);
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
3520b57cec5SDimitry Andric   ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
3560b57cec5SDimitry Andric                                        const NamedDecl *FD,
3570b57cec5SDimitry Andric                                        const MemRegion*) {
3580b57cec5SDimitry Andric   ID.AddInteger(MemRegion::FunctionCodeRegionKind);
3590b57cec5SDimitry Andric   ID.AddPointer(FD);
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
3630b57cec5SDimitry Andric   FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
3670b57cec5SDimitry Andric                                     const BlockDecl *BD, CanQualType,
3680b57cec5SDimitry Andric                                     const AnalysisDeclContext *AC,
3690b57cec5SDimitry Andric                                     const MemRegion*) {
3700b57cec5SDimitry Andric   ID.AddInteger(MemRegion::BlockCodeRegionKind);
3710b57cec5SDimitry Andric   ID.AddPointer(BD);
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
3750b57cec5SDimitry Andric   BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
3790b57cec5SDimitry Andric                                     const BlockCodeRegion *BC,
3800b57cec5SDimitry Andric                                     const LocationContext *LC,
3810b57cec5SDimitry Andric                                     unsigned BlkCount,
3820b57cec5SDimitry Andric                                     const MemRegion *sReg) {
3830b57cec5SDimitry Andric   ID.AddInteger(MemRegion::BlockDataRegionKind);
3840b57cec5SDimitry Andric   ID.AddPointer(BC);
3850b57cec5SDimitry Andric   ID.AddPointer(LC);
3860b57cec5SDimitry Andric   ID.AddInteger(BlkCount);
3870b57cec5SDimitry Andric   ID.AddPointer(sReg);
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
3910b57cec5SDimitry Andric   BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
3920b57cec5SDimitry Andric }
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
3950b57cec5SDimitry Andric                                         Expr const *Ex,
3960b57cec5SDimitry Andric                                         const MemRegion *sReg) {
3970b57cec5SDimitry Andric   ID.AddPointer(Ex);
3980b57cec5SDimitry Andric   ID.AddPointer(sReg);
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
4020b57cec5SDimitry Andric   ProfileRegion(ID, Ex, getSuperRegion());
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
40506c3fb27SDimitry Andric void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
40606c3fb27SDimitry Andric                                                     const Expr *E,
40706c3fb27SDimitry Andric                                                     const ValueDecl *D,
40806c3fb27SDimitry Andric                                                     const MemRegion *sReg) {
40906c3fb27SDimitry Andric   ID.AddPointer(E);
41006c3fb27SDimitry Andric   ID.AddPointer(D);
41106c3fb27SDimitry Andric   ID.AddPointer(sReg);
41206c3fb27SDimitry Andric }
41306c3fb27SDimitry Andric 
41406c3fb27SDimitry Andric void CXXLifetimeExtendedObjectRegion::Profile(
41506c3fb27SDimitry Andric     llvm::FoldingSetNodeID &ID) const {
41606c3fb27SDimitry Andric   ProfileRegion(ID, Ex, ExD, getSuperRegion());
41706c3fb27SDimitry Andric }
41806c3fb27SDimitry Andric 
4190b57cec5SDimitry Andric void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
4200b57cec5SDimitry Andric                                         const CXXRecordDecl *RD,
4210b57cec5SDimitry Andric                                         bool IsVirtual,
4220b57cec5SDimitry Andric                                         const MemRegion *SReg) {
4230b57cec5SDimitry Andric   ID.AddPointer(RD);
4240b57cec5SDimitry Andric   ID.AddBoolean(IsVirtual);
4250b57cec5SDimitry Andric   ID.AddPointer(SReg);
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
4290b57cec5SDimitry Andric   ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
4330b57cec5SDimitry Andric                                            const CXXRecordDecl *RD,
4340b57cec5SDimitry Andric                                            const MemRegion *SReg) {
4350b57cec5SDimitry Andric   ID.AddPointer(RD);
4360b57cec5SDimitry Andric   ID.AddPointer(SReg);
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric void CXXDerivedObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
4400b57cec5SDimitry Andric   ProfileRegion(ID, getDecl(), superRegion);
4410b57cec5SDimitry Andric }
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4440b57cec5SDimitry Andric // Region anchors.
4450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric void GlobalsSpaceRegion::anchor() {}
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric void NonStaticGlobalSpaceRegion::anchor() {}
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric void StackSpaceRegion::anchor() {}
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric void TypedRegion::anchor() {}
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric void TypedValueRegion::anchor() {}
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric void CodeTextRegion::anchor() {}
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric void SubRegion::anchor() {}
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4620b57cec5SDimitry Andric // Region pretty-printing.
4630b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric LLVM_DUMP_METHOD void MemRegion::dump() const {
4660b57cec5SDimitry Andric   dumpToStream(llvm::errs());
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric std::string MemRegion::getString() const {
4700b57cec5SDimitry Andric   std::string s;
4710b57cec5SDimitry Andric   llvm::raw_string_ostream os(s);
4720b57cec5SDimitry Andric   dumpToStream(os);
4730eae32dcSDimitry Andric   return s;
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric void MemRegion::dumpToStream(raw_ostream &os) const {
4770b57cec5SDimitry Andric   os << "<Unknown Region>";
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric void AllocaRegion::dumpToStream(raw_ostream &os) const {
4810b57cec5SDimitry Andric   os << "alloca{S" << Ex->getID(getContext()) << ',' << Cnt << '}';
4820b57cec5SDimitry Andric }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric void FunctionCodeRegion::dumpToStream(raw_ostream &os) const {
4850b57cec5SDimitry Andric   os << "code{" << getDecl()->getDeclName().getAsString() << '}';
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric void BlockCodeRegion::dumpToStream(raw_ostream &os) const {
4890b57cec5SDimitry Andric   os << "block_code{" << static_cast<const void *>(this) << '}';
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric void BlockDataRegion::dumpToStream(raw_ostream &os) const {
4930b57cec5SDimitry Andric   os << "block_data{" << BC;
4940b57cec5SDimitry Andric   os << "; ";
49506c3fb27SDimitry Andric   for (auto Var : referenced_vars())
49606c3fb27SDimitry Andric     os << "(" << Var.getCapturedRegion() << "<-" << Var.getOriginalRegion()
49706c3fb27SDimitry Andric        << ") ";
4980b57cec5SDimitry Andric   os << '}';
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
5020b57cec5SDimitry Andric   // FIXME: More elaborate pretty-printing.
5030b57cec5SDimitry Andric   os << "{ S" << CL->getID(getContext()) <<  " }";
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
50781ad6265SDimitry Andric   os << "temp_object{" << getValueType() << ", "
5080b57cec5SDimitry Andric      << "S" << Ex->getID(getContext()) << '}';
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric 
51106c3fb27SDimitry Andric void CXXLifetimeExtendedObjectRegion::dumpToStream(raw_ostream &os) const {
51206c3fb27SDimitry Andric   os << "lifetime_extended_object{" << getValueType() << ", ";
51306c3fb27SDimitry Andric   if (const IdentifierInfo *ID = ExD->getIdentifier())
51406c3fb27SDimitry Andric     os << ID->getName();
51506c3fb27SDimitry Andric   else
51606c3fb27SDimitry Andric     os << "D" << ExD->getID();
51706c3fb27SDimitry Andric   os << ", "
51806c3fb27SDimitry Andric      << "S" << Ex->getID(getContext()) << '}';
51906c3fb27SDimitry Andric }
52006c3fb27SDimitry Andric 
5210b57cec5SDimitry Andric void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
5220b57cec5SDimitry Andric   os << "Base{" << superRegion << ',' << getDecl()->getName() << '}';
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {
5260b57cec5SDimitry Andric   os << "Derived{" << superRegion << ',' << getDecl()->getName() << '}';
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric void CXXThisRegion::dumpToStream(raw_ostream &os) const {
5300b57cec5SDimitry Andric   os << "this";
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric void ElementRegion::dumpToStream(raw_ostream &os) const {
53481ad6265SDimitry Andric   os << "Element{" << superRegion << ',' << Index << ',' << getElementType()
53581ad6265SDimitry Andric      << '}';
5360b57cec5SDimitry Andric }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric void FieldRegion::dumpToStream(raw_ostream &os) const {
539a7dea167SDimitry Andric   os << superRegion << "." << *getDecl();
5400b57cec5SDimitry Andric }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
5430b57cec5SDimitry Andric   os << "Ivar{" << superRegion << ',' << *getDecl() << '}';
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric void StringRegion::dumpToStream(raw_ostream &os) const {
5470b57cec5SDimitry Andric   assert(Str != nullptr && "Expecting non-null StringLiteral");
5480b57cec5SDimitry Andric   Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
5490b57cec5SDimitry Andric }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
5520b57cec5SDimitry Andric   assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
5530b57cec5SDimitry Andric   Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric void SymbolicRegion::dumpToStream(raw_ostream &os) const {
5570b57cec5SDimitry Andric   if (isa<HeapSpaceRegion>(getSuperRegion()))
5580b57cec5SDimitry Andric     os << "Heap";
5590b57cec5SDimitry Andric   os << "SymRegion{" << sym << '}';
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5625ffd83dbSDimitry Andric void NonParamVarRegion::dumpToStream(raw_ostream &os) const {
5630b57cec5SDimitry Andric   if (const IdentifierInfo *ID = VD->getIdentifier())
5640b57cec5SDimitry Andric     os << ID->getName();
5650b57cec5SDimitry Andric   else
5665ffd83dbSDimitry Andric     os << "NonParamVarRegion{D" << VD->getID() << '}';
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric LLVM_DUMP_METHOD void RegionRawOffset::dump() const {
5700b57cec5SDimitry Andric   dumpToStream(llvm::errs());
5710b57cec5SDimitry Andric }
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric void RegionRawOffset::dumpToStream(raw_ostream &os) const {
5740b57cec5SDimitry Andric   os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric void CodeSpaceRegion::dumpToStream(raw_ostream &os) const {
5780b57cec5SDimitry Andric   os << "CodeSpaceRegion";
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
5820b57cec5SDimitry Andric   os << "StaticGlobalsMemSpace{" << CR << '}';
5830b57cec5SDimitry Andric }
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
5860b57cec5SDimitry Andric   os << "GlobalInternalSpaceRegion";
5870b57cec5SDimitry Andric }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
5900b57cec5SDimitry Andric   os << "GlobalSystemSpaceRegion";
5910b57cec5SDimitry Andric }
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
5940b57cec5SDimitry Andric   os << "GlobalImmutableSpaceRegion";
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
5980b57cec5SDimitry Andric   os << "HeapSpaceRegion";
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
6020b57cec5SDimitry Andric   os << "UnknownSpaceRegion";
6030b57cec5SDimitry Andric }
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
6060b57cec5SDimitry Andric   os << "StackArgumentsSpaceRegion";
6070b57cec5SDimitry Andric }
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
6100b57cec5SDimitry Andric   os << "StackLocalsSpaceRegion";
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
6135ffd83dbSDimitry Andric void ParamVarRegion::dumpToStream(raw_ostream &os) const {
6145ffd83dbSDimitry Andric   const ParmVarDecl *PVD = getDecl();
6155ffd83dbSDimitry Andric   assert(PVD &&
6165ffd83dbSDimitry Andric          "`ParamVarRegion` support functions without `Decl` not implemented"
6175ffd83dbSDimitry Andric          " yet.");
6185ffd83dbSDimitry Andric   if (const IdentifierInfo *ID = PVD->getIdentifier()) {
6195ffd83dbSDimitry Andric     os << ID->getName();
6205ffd83dbSDimitry Andric   } else {
6215ffd83dbSDimitry Andric     os << "ParamVarRegion{P" << PVD->getID() << '}';
6225ffd83dbSDimitry Andric   }
6235ffd83dbSDimitry Andric }
6245ffd83dbSDimitry Andric 
6250b57cec5SDimitry Andric bool MemRegion::canPrintPretty() const {
6260b57cec5SDimitry Andric   return canPrintPrettyAsExpr();
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric bool MemRegion::canPrintPrettyAsExpr() const {
6300b57cec5SDimitry Andric   return false;
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
633*0fca6ea1SDimitry Andric StringRef MemRegion::getKindStr() const {
634*0fca6ea1SDimitry Andric   switch (getKind()) {
635*0fca6ea1SDimitry Andric #define REGION(Id, Parent)                                                     \
636*0fca6ea1SDimitry Andric   case Id##Kind:                                                               \
637*0fca6ea1SDimitry Andric     return #Id;
638*0fca6ea1SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
639*0fca6ea1SDimitry Andric #undef REGION
640*0fca6ea1SDimitry Andric   }
641*0fca6ea1SDimitry Andric   llvm_unreachable("Unkown kind!");
642*0fca6ea1SDimitry Andric }
643*0fca6ea1SDimitry Andric 
6440b57cec5SDimitry Andric void MemRegion::printPretty(raw_ostream &os) const {
6450b57cec5SDimitry Andric   assert(canPrintPretty() && "This region cannot be printed pretty.");
6460b57cec5SDimitry Andric   os << "'";
6470b57cec5SDimitry Andric   printPrettyAsExpr(os);
6480b57cec5SDimitry Andric   os << "'";
6490b57cec5SDimitry Andric }
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric void MemRegion::printPrettyAsExpr(raw_ostream &) const {
6520b57cec5SDimitry Andric   llvm_unreachable("This region cannot be printed pretty.");
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
6555ffd83dbSDimitry Andric bool NonParamVarRegion::canPrintPrettyAsExpr() const { return true; }
6565ffd83dbSDimitry Andric 
6575ffd83dbSDimitry Andric void NonParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
6585ffd83dbSDimitry Andric   os << getDecl()->getName();
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric 
6615ffd83dbSDimitry Andric bool ParamVarRegion::canPrintPrettyAsExpr() const { return true; }
6625ffd83dbSDimitry Andric 
6635ffd83dbSDimitry Andric void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
6645ffd83dbSDimitry Andric   assert(getDecl() &&
6655ffd83dbSDimitry Andric          "`ParamVarRegion` support functions without `Decl` not implemented"
6665ffd83dbSDimitry Andric          " yet.");
6670b57cec5SDimitry Andric   os << getDecl()->getName();
6680b57cec5SDimitry Andric }
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric bool ObjCIvarRegion::canPrintPrettyAsExpr() const {
6710b57cec5SDimitry Andric   return true;
6720b57cec5SDimitry Andric }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
6750b57cec5SDimitry Andric   os << getDecl()->getName();
6760b57cec5SDimitry Andric }
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric bool FieldRegion::canPrintPretty() const {
6790b57cec5SDimitry Andric   return true;
6800b57cec5SDimitry Andric }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric bool FieldRegion::canPrintPrettyAsExpr() const {
6830b57cec5SDimitry Andric   return superRegion->canPrintPrettyAsExpr();
6840b57cec5SDimitry Andric }
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
6870b57cec5SDimitry Andric   assert(canPrintPrettyAsExpr());
6880b57cec5SDimitry Andric   superRegion->printPrettyAsExpr(os);
6890b57cec5SDimitry Andric   os << "." << getDecl()->getName();
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric void FieldRegion::printPretty(raw_ostream &os) const {
6930b57cec5SDimitry Andric   if (canPrintPrettyAsExpr()) {
6940b57cec5SDimitry Andric     os << "\'";
6950b57cec5SDimitry Andric     printPrettyAsExpr(os);
6960b57cec5SDimitry Andric     os << "'";
6970b57cec5SDimitry Andric   } else {
6980b57cec5SDimitry Andric     os << "field " << "\'" << getDecl()->getName() << "'";
6990b57cec5SDimitry Andric   }
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
7030b57cec5SDimitry Andric   return superRegion->canPrintPrettyAsExpr();
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
7070b57cec5SDimitry Andric   superRegion->printPrettyAsExpr(os);
7080b57cec5SDimitry Andric }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric bool CXXDerivedObjectRegion::canPrintPrettyAsExpr() const {
7110b57cec5SDimitry Andric   return superRegion->canPrintPrettyAsExpr();
7120b57cec5SDimitry Andric }
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
7150b57cec5SDimitry Andric   superRegion->printPrettyAsExpr(os);
7160b57cec5SDimitry Andric }
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
7190b57cec5SDimitry Andric   std::string VariableName;
7200b57cec5SDimitry Andric   std::string ArrayIndices;
7210b57cec5SDimitry Andric   const MemRegion *R = this;
7220b57cec5SDimitry Andric   SmallString<50> buf;
7230b57cec5SDimitry Andric   llvm::raw_svector_ostream os(buf);
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   // Obtain array indices to add them to the variable name.
7260b57cec5SDimitry Andric   const ElementRegion *ER = nullptr;
7270b57cec5SDimitry Andric   while ((ER = R->getAs<ElementRegion>())) {
7280b57cec5SDimitry Andric     // Index is a ConcreteInt.
7290b57cec5SDimitry Andric     if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
7300b57cec5SDimitry Andric       llvm::SmallString<2> Idx;
7310b57cec5SDimitry Andric       CI->getValue().toString(Idx);
7320b57cec5SDimitry Andric       ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
7330b57cec5SDimitry Andric     }
734*0fca6ea1SDimitry Andric     // Index is symbolic, but may have a descriptive name.
7350b57cec5SDimitry Andric     else {
736*0fca6ea1SDimitry Andric       auto SI = ER->getIndex().getAs<nonloc::SymbolVal>();
737*0fca6ea1SDimitry Andric       if (!SI)
738*0fca6ea1SDimitry Andric         return "";
739*0fca6ea1SDimitry Andric 
740*0fca6ea1SDimitry Andric       const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
741*0fca6ea1SDimitry Andric       if (!OR)
742*0fca6ea1SDimitry Andric         return "";
743*0fca6ea1SDimitry Andric 
744*0fca6ea1SDimitry Andric       std::string Idx = OR->getDescriptiveName(false);
745*0fca6ea1SDimitry Andric       if (Idx.empty())
746*0fca6ea1SDimitry Andric         return "";
747*0fca6ea1SDimitry Andric 
7480b57cec5SDimitry Andric       ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
7490b57cec5SDimitry Andric     }
7500b57cec5SDimitry Andric     R = ER->getSuperRegion();
7510b57cec5SDimitry Andric   }
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric   // Get variable name.
7540b57cec5SDimitry Andric   if (R && R->canPrintPrettyAsExpr()) {
7550b57cec5SDimitry Andric     R->printPrettyAsExpr(os);
7560b57cec5SDimitry Andric     if (UseQuotes)
7570b57cec5SDimitry Andric       return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
7580b57cec5SDimitry Andric     else
7590b57cec5SDimitry Andric       return (llvm::Twine(os.str()) + ArrayIndices).str();
7600b57cec5SDimitry Andric   }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   return VariableName;
7630b57cec5SDimitry Andric }
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric SourceRange MemRegion::sourceRange() const {
7660b57cec5SDimitry Andric   // Check for more specific regions first.
76706c3fb27SDimitry Andric   if (auto *FR = dyn_cast<FieldRegion>(this)) {
7680b57cec5SDimitry Andric     return FR->getDecl()->getSourceRange();
7690b57cec5SDimitry Andric   }
77006c3fb27SDimitry Andric 
77106c3fb27SDimitry Andric   if (auto *VR = dyn_cast<VarRegion>(this->getBaseRegion())) {
7720b57cec5SDimitry Andric     return VR->getDecl()->getSourceRange();
7730b57cec5SDimitry Andric   }
77406c3fb27SDimitry Andric 
7750b57cec5SDimitry Andric   // Return invalid source range (can be checked by client).
7760b57cec5SDimitry Andric   return {};
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7800b57cec5SDimitry Andric // MemRegionManager methods.
7810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7820b57cec5SDimitry Andric 
7835ffd83dbSDimitry Andric DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
7845ffd83dbSDimitry Andric                                                      SValBuilder &SVB) const {
7855ffd83dbSDimitry Andric   const auto *SR = cast<SubRegion>(MR);
7865ffd83dbSDimitry Andric   SymbolManager &SymMgr = SVB.getSymbolManager();
7875ffd83dbSDimitry Andric 
7885ffd83dbSDimitry Andric   switch (SR->getKind()) {
7895ffd83dbSDimitry Andric   case MemRegion::AllocaRegionKind:
7905ffd83dbSDimitry Andric   case MemRegion::SymbolicRegionKind:
7915ffd83dbSDimitry Andric     return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
7925ffd83dbSDimitry Andric   case MemRegion::StringRegionKind:
7935ffd83dbSDimitry Andric     return SVB.makeIntVal(
7945ffd83dbSDimitry Andric         cast<StringRegion>(SR)->getStringLiteral()->getByteLength() + 1,
7955ffd83dbSDimitry Andric         SVB.getArrayIndexType());
7965ffd83dbSDimitry Andric   case MemRegion::CompoundLiteralRegionKind:
7975ffd83dbSDimitry Andric   case MemRegion::CXXBaseObjectRegionKind:
7985ffd83dbSDimitry Andric   case MemRegion::CXXDerivedObjectRegionKind:
7995ffd83dbSDimitry Andric   case MemRegion::CXXTempObjectRegionKind:
80006c3fb27SDimitry Andric   case MemRegion::CXXLifetimeExtendedObjectRegionKind:
8015ffd83dbSDimitry Andric   case MemRegion::CXXThisRegionKind:
8025ffd83dbSDimitry Andric   case MemRegion::ObjCIvarRegionKind:
8035ffd83dbSDimitry Andric   case MemRegion::NonParamVarRegionKind:
8045ffd83dbSDimitry Andric   case MemRegion::ParamVarRegionKind:
8055ffd83dbSDimitry Andric   case MemRegion::ElementRegionKind:
8065ffd83dbSDimitry Andric   case MemRegion::ObjCStringRegionKind: {
8075ffd83dbSDimitry Andric     QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
8085ffd83dbSDimitry Andric     if (isa<VariableArrayType>(Ty))
8095ffd83dbSDimitry Andric       return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
8105ffd83dbSDimitry Andric 
8115ffd83dbSDimitry Andric     if (Ty->isIncompleteType())
8125ffd83dbSDimitry Andric       return UnknownVal();
8135ffd83dbSDimitry Andric 
814fe6060f1SDimitry Andric     return getElementExtent(Ty, SVB);
8155ffd83dbSDimitry Andric   }
8165ffd83dbSDimitry Andric   case MemRegion::FieldRegionKind: {
8175ffd83dbSDimitry Andric     // Force callers to deal with bitfields explicitly.
8185ffd83dbSDimitry Andric     if (cast<FieldRegion>(SR)->getDecl()->isBitField())
8195ffd83dbSDimitry Andric       return UnknownVal();
8205ffd83dbSDimitry Andric 
8215ffd83dbSDimitry Andric     QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
822349cc55cSDimitry Andric     const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
8235ffd83dbSDimitry Andric 
824349cc55cSDimitry Andric     // We currently don't model flexible array members (FAMs), which are:
825349cc55cSDimitry Andric     //  - int array[]; of IncompleteArrayType
826349cc55cSDimitry Andric     //  - int array[0]; of ConstantArrayType with size 0
82706c3fb27SDimitry Andric     //  - int array[1]; of ConstantArrayType with size 1
828349cc55cSDimitry Andric     // https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
82906c3fb27SDimitry Andric     const auto isFlexibleArrayMemberCandidate =
83006c3fb27SDimitry Andric         [this](const ArrayType *AT) -> bool {
831349cc55cSDimitry Andric       if (!AT)
832349cc55cSDimitry Andric         return false;
833349cc55cSDimitry Andric 
83406c3fb27SDimitry Andric       auto IsIncompleteArray = [](const ArrayType *AT) {
83506c3fb27SDimitry Andric         return isa<IncompleteArrayType>(AT);
83606c3fb27SDimitry Andric       };
83706c3fb27SDimitry Andric       auto IsArrayOfZero = [](const ArrayType *AT) {
83806c3fb27SDimitry Andric         const auto *CAT = dyn_cast<ConstantArrayType>(AT);
839*0fca6ea1SDimitry Andric         return CAT && CAT->isZeroSize();
84006c3fb27SDimitry Andric       };
84106c3fb27SDimitry Andric       auto IsArrayOfOne = [](const ArrayType *AT) {
84206c3fb27SDimitry Andric         const auto *CAT = dyn_cast<ConstantArrayType>(AT);
84306c3fb27SDimitry Andric         return CAT && CAT->getSize() == 1;
84406c3fb27SDimitry Andric       };
84506c3fb27SDimitry Andric 
846bdd1243dSDimitry Andric       using FAMKind = LangOptions::StrictFlexArraysLevelKind;
847bdd1243dSDimitry Andric       const FAMKind StrictFlexArraysLevel =
848bdd1243dSDimitry Andric           Ctx.getLangOpts().getStrictFlexArraysLevel();
849bdd1243dSDimitry Andric 
85006c3fb27SDimitry Andric       // "Default": Any trailing array member is a FAM.
85106c3fb27SDimitry Andric       // Since we cannot tell at this point if this array is a trailing member
85206c3fb27SDimitry Andric       // or not, let's just do the same as for "OneZeroOrIncomplete".
85306c3fb27SDimitry Andric       if (StrictFlexArraysLevel == FAMKind::Default)
85406c3fb27SDimitry Andric         return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
855349cc55cSDimitry Andric 
85606c3fb27SDimitry Andric       if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
85706c3fb27SDimitry Andric         return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
85806c3fb27SDimitry Andric 
85906c3fb27SDimitry Andric       if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
86006c3fb27SDimitry Andric         return IsArrayOfZero(AT) || IsIncompleteArray(AT);
86106c3fb27SDimitry Andric 
86206c3fb27SDimitry Andric       assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
86306c3fb27SDimitry Andric       return IsIncompleteArray(AT);
864349cc55cSDimitry Andric     };
865349cc55cSDimitry Andric 
86606c3fb27SDimitry Andric     if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
867349cc55cSDimitry Andric       return UnknownVal();
8685ffd83dbSDimitry Andric 
8695ffd83dbSDimitry Andric     return Size;
8705ffd83dbSDimitry Andric   }
8715ffd83dbSDimitry Andric     // FIXME: The following are being used in 'SimpleSValBuilder' and in
8725ffd83dbSDimitry Andric     // 'ArrayBoundChecker::checkLocation' because there is no symbol to
8735ffd83dbSDimitry Andric     // represent the regions more appropriately.
8745ffd83dbSDimitry Andric   case MemRegion::BlockDataRegionKind:
8755ffd83dbSDimitry Andric   case MemRegion::BlockCodeRegionKind:
8765ffd83dbSDimitry Andric   case MemRegion::FunctionCodeRegionKind:
8775ffd83dbSDimitry Andric     return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
8785ffd83dbSDimitry Andric   default:
8795ffd83dbSDimitry Andric     llvm_unreachable("Unhandled region");
8805ffd83dbSDimitry Andric   }
8815ffd83dbSDimitry Andric }
8825ffd83dbSDimitry Andric 
8830b57cec5SDimitry Andric template <typename REG>
8840b57cec5SDimitry Andric const REG *MemRegionManager::LazyAllocate(REG*& region) {
8850b57cec5SDimitry Andric   if (!region) {
88606c3fb27SDimitry Andric     region = new (A) REG(*this);
8870b57cec5SDimitry Andric   }
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   return region;
8900b57cec5SDimitry Andric }
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric template <typename REG, typename ARG>
8930b57cec5SDimitry Andric const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
8940b57cec5SDimitry Andric   if (!region) {
89506c3fb27SDimitry Andric     region = new (A) REG(this, a);
8960b57cec5SDimitry Andric   }
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   return region;
8990b57cec5SDimitry Andric }
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric const StackLocalsSpaceRegion*
9020b57cec5SDimitry Andric MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
9030b57cec5SDimitry Andric   assert(STC);
9040b57cec5SDimitry Andric   StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   if (R)
9070b57cec5SDimitry Andric     return R;
9080b57cec5SDimitry Andric 
90906c3fb27SDimitry Andric   R = new (A) StackLocalsSpaceRegion(*this, STC);
9100b57cec5SDimitry Andric   return R;
9110b57cec5SDimitry Andric }
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric const StackArgumentsSpaceRegion *
9140b57cec5SDimitry Andric MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
9150b57cec5SDimitry Andric   assert(STC);
9160b57cec5SDimitry Andric   StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   if (R)
9190b57cec5SDimitry Andric     return R;
9200b57cec5SDimitry Andric 
92106c3fb27SDimitry Andric   R = new (A) StackArgumentsSpaceRegion(*this, STC);
9220b57cec5SDimitry Andric   return R;
9230b57cec5SDimitry Andric }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric const GlobalsSpaceRegion
9260b57cec5SDimitry Andric *MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
9270b57cec5SDimitry Andric                                     const CodeTextRegion *CR) {
9280b57cec5SDimitry Andric   if (!CR) {
9290b57cec5SDimitry Andric     if (K == MemRegion::GlobalSystemSpaceRegionKind)
9300b57cec5SDimitry Andric       return LazyAllocate(SystemGlobals);
9310b57cec5SDimitry Andric     if (K == MemRegion::GlobalImmutableSpaceRegionKind)
9320b57cec5SDimitry Andric       return LazyAllocate(ImmutableGlobals);
9330b57cec5SDimitry Andric     assert(K == MemRegion::GlobalInternalSpaceRegionKind);
9340b57cec5SDimitry Andric     return LazyAllocate(InternalGlobals);
9350b57cec5SDimitry Andric   }
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric   assert(K == MemRegion::StaticGlobalSpaceRegionKind);
9380b57cec5SDimitry Andric   StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
9390b57cec5SDimitry Andric   if (R)
9400b57cec5SDimitry Andric     return R;
9410b57cec5SDimitry Andric 
94206c3fb27SDimitry Andric   R = new (A) StaticGlobalSpaceRegion(*this, CR);
9430b57cec5SDimitry Andric   return R;
9440b57cec5SDimitry Andric }
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
9470b57cec5SDimitry Andric   return LazyAllocate(heap);
9480b57cec5SDimitry Andric }
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric const UnknownSpaceRegion *MemRegionManager::getUnknownRegion() {
9510b57cec5SDimitry Andric   return LazyAllocate(unknown);
9520b57cec5SDimitry Andric }
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
9550b57cec5SDimitry Andric   return LazyAllocate(code);
9560b57cec5SDimitry Andric }
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9590b57cec5SDimitry Andric // Constructing regions.
9600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric const StringRegion *MemRegionManager::getStringRegion(const StringLiteral *Str){
9630b57cec5SDimitry Andric   return getSubRegion<StringRegion>(
9640b57cec5SDimitry Andric       Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric const ObjCStringRegion *
9680b57cec5SDimitry Andric MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){
9690b57cec5SDimitry Andric   return getSubRegion<ObjCStringRegion>(
9700b57cec5SDimitry Andric       Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
9710b57cec5SDimitry Andric }
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric /// Look through a chain of LocationContexts to either find the
9740b57cec5SDimitry Andric /// StackFrameContext that matches a DeclContext, or find a VarRegion
9750b57cec5SDimitry Andric /// for a variable captured by a block.
9760b57cec5SDimitry Andric static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
9770b57cec5SDimitry Andric getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
9780b57cec5SDimitry Andric                                       const DeclContext *DC,
9790b57cec5SDimitry Andric                                       const VarDecl *VD) {
9800b57cec5SDimitry Andric   while (LC) {
9810b57cec5SDimitry Andric     if (const auto *SFC = dyn_cast<StackFrameContext>(LC)) {
9820b57cec5SDimitry Andric       if (cast<DeclContext>(SFC->getDecl()) == DC)
9830b57cec5SDimitry Andric         return SFC;
9840b57cec5SDimitry Andric     }
9850b57cec5SDimitry Andric     if (const auto *BC = dyn_cast<BlockInvocationContext>(LC)) {
9865ffd83dbSDimitry Andric       const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
9870b57cec5SDimitry Andric       // FIXME: This can be made more efficient.
98806c3fb27SDimitry Andric       for (auto Var : BR->referenced_vars()) {
98906c3fb27SDimitry Andric         const TypedValueRegion *OrigR = Var.getOriginalRegion();
9905ffd83dbSDimitry Andric         if (const auto *VR = dyn_cast<VarRegion>(OrigR)) {
9910b57cec5SDimitry Andric           if (VR->getDecl() == VD)
99206c3fb27SDimitry Andric             return cast<VarRegion>(Var.getCapturedRegion());
9930b57cec5SDimitry Andric         }
9940b57cec5SDimitry Andric       }
9955ffd83dbSDimitry Andric     }
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric     LC = LC->getParent();
9980b57cec5SDimitry Andric   }
9990b57cec5SDimitry Andric   return (const StackFrameContext *)nullptr;
10000b57cec5SDimitry Andric }
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
10030b57cec5SDimitry Andric                                                 const LocationContext *LC) {
10045ffd83dbSDimitry Andric   const auto *PVD = dyn_cast<ParmVarDecl>(D);
10055ffd83dbSDimitry Andric   if (PVD) {
10065ffd83dbSDimitry Andric     unsigned Index = PVD->getFunctionScopeIndex();
10075ffd83dbSDimitry Andric     const StackFrameContext *SFC = LC->getStackFrame();
10085ffd83dbSDimitry Andric     const Stmt *CallSite = SFC->getCallSite();
10095ffd83dbSDimitry Andric     if (CallSite) {
10105ffd83dbSDimitry Andric       const Decl *D = SFC->getDecl();
10115ffd83dbSDimitry Andric       if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
10125ffd83dbSDimitry Andric         if (Index < FD->param_size() && FD->parameters()[Index] == PVD)
10135ffd83dbSDimitry Andric           return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
10145ffd83dbSDimitry Andric                                               getStackArgumentsRegion(SFC));
10155ffd83dbSDimitry Andric       } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
10165ffd83dbSDimitry Andric         if (Index < BD->param_size() && BD->parameters()[Index] == PVD)
10175ffd83dbSDimitry Andric           return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
10185ffd83dbSDimitry Andric                                               getStackArgumentsRegion(SFC));
10195ffd83dbSDimitry Andric       } else {
10205ffd83dbSDimitry Andric         return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
10215ffd83dbSDimitry Andric                                             getStackArgumentsRegion(SFC));
10225ffd83dbSDimitry Andric       }
10235ffd83dbSDimitry Andric     }
10245ffd83dbSDimitry Andric   }
10255ffd83dbSDimitry Andric 
10260b57cec5SDimitry Andric   D = D->getCanonicalDecl();
10270b57cec5SDimitry Andric   const MemRegion *sReg = nullptr;
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
103081ad6265SDimitry Andric     QualType Ty = D->getType();
103181ad6265SDimitry Andric     assert(!Ty.isNull());
103281ad6265SDimitry Andric     if (Ty.isConstQualified()) {
103381ad6265SDimitry Andric       sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
103481ad6265SDimitry Andric     } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
10350b57cec5SDimitry Andric       sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
10360b57cec5SDimitry Andric     } else {
103781ad6265SDimitry Andric       sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
10380b57cec5SDimitry Andric     }
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric   // Finally handle static locals.
10410b57cec5SDimitry Andric   } else {
10420b57cec5SDimitry Andric     // FIXME: Once we implement scope handling, we will need to properly lookup
10430b57cec5SDimitry Andric     // 'D' to the proper LocationContext.
10440b57cec5SDimitry Andric     const DeclContext *DC = D->getDeclContext();
10450b57cec5SDimitry Andric     llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
10460b57cec5SDimitry Andric       getStackOrCaptureRegionForDeclContext(LC, DC, D);
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric     if (V.is<const VarRegion*>())
10490b57cec5SDimitry Andric       return V.get<const VarRegion*>();
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric     const auto *STC = V.get<const StackFrameContext *>();
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric     if (!STC) {
10540b57cec5SDimitry Andric       // FIXME: Assign a more sensible memory space to static locals
10550b57cec5SDimitry Andric       // we see from within blocks that we analyze as top-level declarations.
10560b57cec5SDimitry Andric       sReg = getUnknownRegion();
10570b57cec5SDimitry Andric     } else {
10580b57cec5SDimitry Andric       if (D->hasLocalStorage()) {
1059349cc55cSDimitry Andric         sReg =
1060349cc55cSDimitry Andric             isa<ParmVarDecl, ImplicitParamDecl>(D)
10610b57cec5SDimitry Andric                 ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
10620b57cec5SDimitry Andric                 : static_cast<const MemRegion *>(getStackLocalsRegion(STC));
10630b57cec5SDimitry Andric       }
10640b57cec5SDimitry Andric       else {
10650b57cec5SDimitry Andric         assert(D->isStaticLocal());
10660b57cec5SDimitry Andric         const Decl *STCD = STC->getDecl();
1067349cc55cSDimitry Andric         if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
10680b57cec5SDimitry Andric           sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
10690b57cec5SDimitry Andric                                   getFunctionCodeRegion(cast<NamedDecl>(STCD)));
10700b57cec5SDimitry Andric         else if (const auto *BD = dyn_cast<BlockDecl>(STCD)) {
10710b57cec5SDimitry Andric           // FIXME: The fallback type here is totally bogus -- though it should
10720b57cec5SDimitry Andric           // never be queried, it will prevent uniquing with the real
10730b57cec5SDimitry Andric           // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
10740b57cec5SDimitry Andric           // signature.
10750b57cec5SDimitry Andric           QualType T;
10760b57cec5SDimitry Andric           if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
10770b57cec5SDimitry Andric             T = TSI->getType();
10780b57cec5SDimitry Andric           if (T.isNull())
10790b57cec5SDimitry Andric             T = getContext().VoidTy;
108081ad6265SDimitry Andric           if (!T->getAs<FunctionType>()) {
108181ad6265SDimitry Andric             FunctionProtoType::ExtProtoInfo Ext;
1082bdd1243dSDimitry Andric             T = getContext().getFunctionType(T, std::nullopt, Ext);
108381ad6265SDimitry Andric           }
10840b57cec5SDimitry Andric           T = getContext().getBlockPointerType(T);
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric           const BlockCodeRegion *BTR =
10875ffd83dbSDimitry Andric             getBlockCodeRegion(BD, Ctx.getCanonicalType(T),
10880b57cec5SDimitry Andric                                STC->getAnalysisDeclContext());
10890b57cec5SDimitry Andric           sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
10900b57cec5SDimitry Andric                                   BTR);
10910b57cec5SDimitry Andric         }
10920b57cec5SDimitry Andric         else {
10930b57cec5SDimitry Andric           sReg = getGlobalsRegion();
10940b57cec5SDimitry Andric         }
10950b57cec5SDimitry Andric       }
10960b57cec5SDimitry Andric     }
10970b57cec5SDimitry Andric   }
10980b57cec5SDimitry Andric 
109906c3fb27SDimitry Andric   return getNonParamVarRegion(D, sReg);
11000b57cec5SDimitry Andric }
11010b57cec5SDimitry Andric 
11025ffd83dbSDimitry Andric const NonParamVarRegion *
11035ffd83dbSDimitry Andric MemRegionManager::getNonParamVarRegion(const VarDecl *D,
11040b57cec5SDimitry Andric                                        const MemRegion *superR) {
110506c3fb27SDimitry Andric   // Prefer the definition over the canonical decl as the canonical form.
11060b57cec5SDimitry Andric   D = D->getCanonicalDecl();
110706c3fb27SDimitry Andric   if (const VarDecl *Def = D->getDefinition())
110806c3fb27SDimitry Andric     D = Def;
11095ffd83dbSDimitry Andric   return getSubRegion<NonParamVarRegion>(D, superR);
11105ffd83dbSDimitry Andric }
11115ffd83dbSDimitry Andric 
11125ffd83dbSDimitry Andric const ParamVarRegion *
11135ffd83dbSDimitry Andric MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
11145ffd83dbSDimitry Andric                                     const LocationContext *LC) {
11155ffd83dbSDimitry Andric   const StackFrameContext *SFC = LC->getStackFrame();
11165ffd83dbSDimitry Andric   assert(SFC);
11175ffd83dbSDimitry Andric   return getSubRegion<ParamVarRegion>(OriginExpr, Index,
11185ffd83dbSDimitry Andric                                       getStackArgumentsRegion(SFC));
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric 
11210b57cec5SDimitry Andric const BlockDataRegion *
11220b57cec5SDimitry Andric MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
11230b57cec5SDimitry Andric                                      const LocationContext *LC,
11240b57cec5SDimitry Andric                                      unsigned blockCount) {
11250b57cec5SDimitry Andric   const MemSpaceRegion *sReg = nullptr;
11260b57cec5SDimitry Andric   const BlockDecl *BD = BC->getDecl();
11270b57cec5SDimitry Andric   if (!BD->hasCaptures()) {
11280b57cec5SDimitry Andric     // This handles 'static' blocks.
11290b57cec5SDimitry Andric     sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
11300b57cec5SDimitry Andric   }
11310b57cec5SDimitry Andric   else {
1132bdd1243dSDimitry Andric     bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1133bdd1243dSDimitry Andric 
1134bdd1243dSDimitry Andric     // ARC managed blocks can be initialized on stack or directly in heap
1135bdd1243dSDimitry Andric     // depending on the implementations.  So we initialize them with
1136bdd1243dSDimitry Andric     // UnknownRegion.
1137bdd1243dSDimitry Andric     if (!IsArcManagedBlock && LC) {
11380b57cec5SDimitry Andric       // FIXME: Once we implement scope handling, we want the parent region
11390b57cec5SDimitry Andric       // to be the scope.
11400b57cec5SDimitry Andric       const StackFrameContext *STC = LC->getStackFrame();
11410b57cec5SDimitry Andric       assert(STC);
11420b57cec5SDimitry Andric       sReg = getStackLocalsRegion(STC);
1143bdd1243dSDimitry Andric     } else {
11440b57cec5SDimitry Andric       // We allow 'LC' to be NULL for cases where want BlockDataRegions
11450b57cec5SDimitry Andric       // without context-sensitivity.
11460b57cec5SDimitry Andric       sReg = getUnknownRegion();
11470b57cec5SDimitry Andric     }
11480b57cec5SDimitry Andric   }
11490b57cec5SDimitry Andric 
11500b57cec5SDimitry Andric   return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric const CompoundLiteralRegion*
11540b57cec5SDimitry Andric MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
11550b57cec5SDimitry Andric                                            const LocationContext *LC) {
11560b57cec5SDimitry Andric   const MemSpaceRegion *sReg = nullptr;
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   if (CL->isFileScope())
11590b57cec5SDimitry Andric     sReg = getGlobalsRegion();
11600b57cec5SDimitry Andric   else {
11610b57cec5SDimitry Andric     const StackFrameContext *STC = LC->getStackFrame();
11620b57cec5SDimitry Andric     assert(STC);
11630b57cec5SDimitry Andric     sReg = getStackLocalsRegion(STC);
11640b57cec5SDimitry Andric   }
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   return getSubRegion<CompoundLiteralRegion>(CL, sReg);
11670b57cec5SDimitry Andric }
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric const ElementRegion *
11700b57cec5SDimitry Andric MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
11710b57cec5SDimitry Andric                                    const SubRegion *superRegion,
1172*0fca6ea1SDimitry Andric                                    const ASTContext &Ctx) {
11730b57cec5SDimitry Andric   QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
11760b57cec5SDimitry Andric   ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric   void *InsertPos;
11790b57cec5SDimitry Andric   MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
11800b57cec5SDimitry Andric   auto *R = cast_or_null<ElementRegion>(data);
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric   if (!R) {
118306c3fb27SDimitry Andric     R = new (A) ElementRegion(T, Idx, superRegion);
11840b57cec5SDimitry Andric     Regions.InsertNode(R, InsertPos);
11850b57cec5SDimitry Andric   }
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric   return R;
11880b57cec5SDimitry Andric }
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric const FunctionCodeRegion *
11910b57cec5SDimitry Andric MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) {
11920b57cec5SDimitry Andric   // To think: should we canonicalize the declaration here?
11930b57cec5SDimitry Andric   return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
11940b57cec5SDimitry Andric }
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric const BlockCodeRegion *
11970b57cec5SDimitry Andric MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy,
11980b57cec5SDimitry Andric                                      AnalysisDeclContext *AC) {
11990b57cec5SDimitry Andric   return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion());
12000b57cec5SDimitry Andric }
12010b57cec5SDimitry Andric 
120281ad6265SDimitry Andric const SymbolicRegion *
120381ad6265SDimitry Andric MemRegionManager::getSymbolicRegion(SymbolRef sym,
120481ad6265SDimitry Andric                                     const MemSpaceRegion *MemSpace) {
120581ad6265SDimitry Andric   if (MemSpace == nullptr)
120681ad6265SDimitry Andric     MemSpace = getUnknownRegion();
120781ad6265SDimitry Andric   return getSubRegion<SymbolicRegion>(sym, MemSpace);
12080b57cec5SDimitry Andric }
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
12110b57cec5SDimitry Andric   return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
12120b57cec5SDimitry Andric }
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric const FieldRegion*
12150b57cec5SDimitry Andric MemRegionManager::getFieldRegion(const FieldDecl *d,
12160b57cec5SDimitry Andric                                  const SubRegion* superRegion){
12170b57cec5SDimitry Andric   return getSubRegion<FieldRegion>(d, superRegion);
12180b57cec5SDimitry Andric }
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric const ObjCIvarRegion*
12210b57cec5SDimitry Andric MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
12220b57cec5SDimitry Andric                                     const SubRegion* superRegion) {
12230b57cec5SDimitry Andric   return getSubRegion<ObjCIvarRegion>(d, superRegion);
12240b57cec5SDimitry Andric }
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric const CXXTempObjectRegion*
12270b57cec5SDimitry Andric MemRegionManager::getCXXTempObjectRegion(Expr const *E,
12280b57cec5SDimitry Andric                                          LocationContext const *LC) {
12290b57cec5SDimitry Andric   const StackFrameContext *SFC = LC->getStackFrame();
12300b57cec5SDimitry Andric   assert(SFC);
12310b57cec5SDimitry Andric   return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
123406c3fb27SDimitry Andric const CXXLifetimeExtendedObjectRegion *
123506c3fb27SDimitry Andric MemRegionManager::getCXXLifetimeExtendedObjectRegion(
123606c3fb27SDimitry Andric     const Expr *Ex, const ValueDecl *VD, const LocationContext *LC) {
123706c3fb27SDimitry Andric   const StackFrameContext *SFC = LC->getStackFrame();
123806c3fb27SDimitry Andric   assert(SFC);
123906c3fb27SDimitry Andric   return getSubRegion<CXXLifetimeExtendedObjectRegion>(
124006c3fb27SDimitry Andric       Ex, VD, getStackLocalsRegion(SFC));
124106c3fb27SDimitry Andric }
124206c3fb27SDimitry Andric 
124306c3fb27SDimitry Andric const CXXLifetimeExtendedObjectRegion *
124406c3fb27SDimitry Andric MemRegionManager::getCXXStaticLifetimeExtendedObjectRegion(
124506c3fb27SDimitry Andric     const Expr *Ex, const ValueDecl *VD) {
124606c3fb27SDimitry Andric   return getSubRegion<CXXLifetimeExtendedObjectRegion>(
124706c3fb27SDimitry Andric       Ex, VD,
124806c3fb27SDimitry Andric       getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
124906c3fb27SDimitry Andric }
125006c3fb27SDimitry Andric 
12510b57cec5SDimitry Andric /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
12520b57cec5SDimitry Andric /// class of the type of \p Super.
12530b57cec5SDimitry Andric static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
12540b57cec5SDimitry Andric                              const TypedValueRegion *Super,
12550b57cec5SDimitry Andric                              bool IsVirtual) {
12560b57cec5SDimitry Andric   BaseClass = BaseClass->getCanonicalDecl();
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
12590b57cec5SDimitry Andric   if (!Class)
12600b57cec5SDimitry Andric     return true;
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   if (IsVirtual)
12630b57cec5SDimitry Andric     return Class->isVirtuallyDerivedFrom(BaseClass);
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric   for (const auto &I : Class->bases()) {
12660b57cec5SDimitry Andric     if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
12670b57cec5SDimitry Andric       return true;
12680b57cec5SDimitry Andric   }
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric   return false;
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric const CXXBaseObjectRegion *
12740b57cec5SDimitry Andric MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
12750b57cec5SDimitry Andric                                          const SubRegion *Super,
12760b57cec5SDimitry Andric                                          bool IsVirtual) {
12770b57cec5SDimitry Andric   if (isa<TypedValueRegion>(Super)) {
1278a7dea167SDimitry Andric     assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual));
12790b57cec5SDimitry Andric     (void)&isValidBaseClass;
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric     if (IsVirtual) {
12820b57cec5SDimitry Andric       // Virtual base regions should not be layered, since the layout rules
12830b57cec5SDimitry Andric       // are different.
12840b57cec5SDimitry Andric       while (const auto *Base = dyn_cast<CXXBaseObjectRegion>(Super))
12850b57cec5SDimitry Andric         Super = cast<SubRegion>(Base->getSuperRegion());
12860b57cec5SDimitry Andric       assert(Super && !isa<MemSpaceRegion>(Super));
12870b57cec5SDimitry Andric     }
12880b57cec5SDimitry Andric   }
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric   return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
12910b57cec5SDimitry Andric }
12920b57cec5SDimitry Andric 
12930b57cec5SDimitry Andric const CXXDerivedObjectRegion *
12940b57cec5SDimitry Andric MemRegionManager::getCXXDerivedObjectRegion(const CXXRecordDecl *RD,
12950b57cec5SDimitry Andric                                             const SubRegion *Super) {
12960b57cec5SDimitry Andric   return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric 
12990b57cec5SDimitry Andric const CXXThisRegion*
13000b57cec5SDimitry Andric MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
13010b57cec5SDimitry Andric                                    const LocationContext *LC) {
13020b57cec5SDimitry Andric   const auto *PT = thisPointerTy->getAs<PointerType>();
13030b57cec5SDimitry Andric   assert(PT);
13040b57cec5SDimitry Andric   // Inside the body of the operator() of a lambda a this expr might refer to an
13050b57cec5SDimitry Andric   // object in one of the parent location contexts.
13060b57cec5SDimitry Andric   const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl());
13070b57cec5SDimitry Andric   // FIXME: when operator() of lambda is analyzed as a top level function and
13080b57cec5SDimitry Andric   // 'this' refers to a this to the enclosing scope, there is no right region to
13090b57cec5SDimitry Andric   // return.
13100b57cec5SDimitry Andric   while (!LC->inTopFrame() && (!D || D->isStatic() ||
13110b57cec5SDimitry Andric                                PT != D->getThisType()->getAs<PointerType>())) {
13120b57cec5SDimitry Andric     LC = LC->getParent();
13130b57cec5SDimitry Andric     D = dyn_cast<CXXMethodDecl>(LC->getDecl());
13140b57cec5SDimitry Andric   }
13150b57cec5SDimitry Andric   const StackFrameContext *STC = LC->getStackFrame();
13160b57cec5SDimitry Andric   assert(STC);
13170b57cec5SDimitry Andric   return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
13180b57cec5SDimitry Andric }
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric const AllocaRegion*
13210b57cec5SDimitry Andric MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
13220b57cec5SDimitry Andric                                   const LocationContext *LC) {
13230b57cec5SDimitry Andric   const StackFrameContext *STC = LC->getStackFrame();
13240b57cec5SDimitry Andric   assert(STC);
13250b57cec5SDimitry Andric   return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric const MemSpaceRegion *MemRegion::getMemorySpace() const {
13290b57cec5SDimitry Andric   const MemRegion *R = this;
13300b57cec5SDimitry Andric   const auto *SR = dyn_cast<SubRegion>(this);
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   while (SR) {
13330b57cec5SDimitry Andric     R = SR->getSuperRegion();
13340b57cec5SDimitry Andric     SR = dyn_cast<SubRegion>(R);
13350b57cec5SDimitry Andric   }
13360b57cec5SDimitry Andric 
133706c3fb27SDimitry Andric   return cast<MemSpaceRegion>(R);
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric bool MemRegion::hasStackStorage() const {
13410b57cec5SDimitry Andric   return isa<StackSpaceRegion>(getMemorySpace());
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric bool MemRegion::hasStackNonParametersStorage() const {
13450b57cec5SDimitry Andric   return isa<StackLocalsSpaceRegion>(getMemorySpace());
13460b57cec5SDimitry Andric }
13470b57cec5SDimitry Andric 
13480b57cec5SDimitry Andric bool MemRegion::hasStackParametersStorage() const {
13490b57cec5SDimitry Andric   return isa<StackArgumentsSpaceRegion>(getMemorySpace());
13500b57cec5SDimitry Andric }
13510b57cec5SDimitry Andric 
1352bdd1243dSDimitry Andric // Strips away all elements and fields.
1353bdd1243dSDimitry Andric // Returns the base region of them.
13540b57cec5SDimitry Andric const MemRegion *MemRegion::getBaseRegion() const {
13550b57cec5SDimitry Andric   const MemRegion *R = this;
13560b57cec5SDimitry Andric   while (true) {
13570b57cec5SDimitry Andric     switch (R->getKind()) {
13580b57cec5SDimitry Andric       case MemRegion::ElementRegionKind:
13590b57cec5SDimitry Andric       case MemRegion::FieldRegionKind:
13600b57cec5SDimitry Andric       case MemRegion::ObjCIvarRegionKind:
13610b57cec5SDimitry Andric       case MemRegion::CXXBaseObjectRegionKind:
13620b57cec5SDimitry Andric       case MemRegion::CXXDerivedObjectRegionKind:
13630b57cec5SDimitry Andric         R = cast<SubRegion>(R)->getSuperRegion();
13640b57cec5SDimitry Andric         continue;
13650b57cec5SDimitry Andric       default:
13660b57cec5SDimitry Andric         break;
13670b57cec5SDimitry Andric     }
13680b57cec5SDimitry Andric     break;
13690b57cec5SDimitry Andric   }
13700b57cec5SDimitry Andric   return R;
13710b57cec5SDimitry Andric }
13720b57cec5SDimitry Andric 
1373bdd1243dSDimitry Andric // Returns the region of the root class of a C++ class hierarchy.
13740b57cec5SDimitry Andric const MemRegion *MemRegion::getMostDerivedObjectRegion() const {
13750b57cec5SDimitry Andric   const MemRegion *R = this;
13760b57cec5SDimitry Andric   while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
13770b57cec5SDimitry Andric     R = BR->getSuperRegion();
13780b57cec5SDimitry Andric   return R;
13790b57cec5SDimitry Andric }
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric bool MemRegion::isSubRegionOf(const MemRegion *) const {
13820b57cec5SDimitry Andric   return false;
13830b57cec5SDimitry Andric }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13860b57cec5SDimitry Andric // View handling.
13870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {
13900b57cec5SDimitry Andric   const MemRegion *R = this;
13910b57cec5SDimitry Andric   while (true) {
13920b57cec5SDimitry Andric     switch (R->getKind()) {
13930b57cec5SDimitry Andric     case ElementRegionKind: {
13940b57cec5SDimitry Andric       const auto *ER = cast<ElementRegion>(R);
13950b57cec5SDimitry Andric       if (!ER->getIndex().isZeroConstant())
13960b57cec5SDimitry Andric         return R;
13970b57cec5SDimitry Andric       R = ER->getSuperRegion();
13980b57cec5SDimitry Andric       break;
13990b57cec5SDimitry Andric     }
14000b57cec5SDimitry Andric     case CXXBaseObjectRegionKind:
14010b57cec5SDimitry Andric     case CXXDerivedObjectRegionKind:
14020b57cec5SDimitry Andric       if (!StripBaseAndDerivedCasts)
14030b57cec5SDimitry Andric         return R;
14040b57cec5SDimitry Andric       R = cast<TypedValueRegion>(R)->getSuperRegion();
14050b57cec5SDimitry Andric       break;
14060b57cec5SDimitry Andric     default:
14070b57cec5SDimitry Andric       return R;
14080b57cec5SDimitry Andric     }
14090b57cec5SDimitry Andric   }
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric 
14120b57cec5SDimitry Andric const SymbolicRegion *MemRegion::getSymbolicBase() const {
14130b57cec5SDimitry Andric   const auto *SubR = dyn_cast<SubRegion>(this);
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   while (SubR) {
14160b57cec5SDimitry Andric     if (const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
14170b57cec5SDimitry Andric       return SymR;
14180b57cec5SDimitry Andric     SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
14190b57cec5SDimitry Andric   }
14200b57cec5SDimitry Andric   return nullptr;
14210b57cec5SDimitry Andric }
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric RegionRawOffset ElementRegion::getAsArrayOffset() const {
14240b57cec5SDimitry Andric   int64_t offset = 0;
14250b57cec5SDimitry Andric   const ElementRegion *ER = this;
14260b57cec5SDimitry Andric   const MemRegion *superR = nullptr;
14270b57cec5SDimitry Andric   ASTContext &C = getContext();
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric   // FIXME: Handle multi-dimensional arrays.
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   while (ER) {
14320b57cec5SDimitry Andric     superR = ER->getSuperRegion();
14330b57cec5SDimitry Andric 
14340b57cec5SDimitry Andric     // FIXME: generalize to symbolic offsets.
14350b57cec5SDimitry Andric     SVal index = ER->getIndex();
14360b57cec5SDimitry Andric     if (auto CI = index.getAs<nonloc::ConcreteInt>()) {
14370b57cec5SDimitry Andric       // Update the offset.
14380b57cec5SDimitry Andric       int64_t i = CI->getValue().getSExtValue();
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric       if (i != 0) {
14410b57cec5SDimitry Andric         QualType elemType = ER->getElementType();
14420b57cec5SDimitry Andric 
14430b57cec5SDimitry Andric         // If we are pointing to an incomplete type, go no further.
14440b57cec5SDimitry Andric         if (elemType->isIncompleteType()) {
14450b57cec5SDimitry Andric           superR = ER;
14460b57cec5SDimitry Andric           break;
14470b57cec5SDimitry Andric         }
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric         int64_t size = C.getTypeSizeInChars(elemType).getQuantity();
14500b57cec5SDimitry Andric         if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
14510b57cec5SDimitry Andric           offset = *NewOffset;
14520b57cec5SDimitry Andric         } else {
14530b57cec5SDimitry Andric           LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: "
14540b57cec5SDimitry Andric                                   << "offset overflowing, returning unknown\n");
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric           return nullptr;
14570b57cec5SDimitry Andric         }
14580b57cec5SDimitry Andric       }
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric       // Go to the next ElementRegion (if any).
14610b57cec5SDimitry Andric       ER = dyn_cast<ElementRegion>(superR);
14620b57cec5SDimitry Andric       continue;
14630b57cec5SDimitry Andric     }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric     return nullptr;
14660b57cec5SDimitry Andric   }
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric   assert(superR && "super region cannot be NULL");
14690b57cec5SDimitry Andric   return RegionRawOffset(superR, CharUnits::fromQuantity(offset));
14700b57cec5SDimitry Andric }
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric /// Returns true if \p Base is an immediate base class of \p Child
14730b57cec5SDimitry Andric static bool isImmediateBase(const CXXRecordDecl *Child,
14740b57cec5SDimitry Andric                             const CXXRecordDecl *Base) {
14750b57cec5SDimitry Andric   assert(Child && "Child must not be null");
14760b57cec5SDimitry Andric   // Note that we do NOT canonicalize the base class here, because
14770b57cec5SDimitry Andric   // ASTRecordLayout doesn't either. If that leads us down the wrong path,
14780b57cec5SDimitry Andric   // so be it; at least we won't crash.
14790b57cec5SDimitry Andric   for (const auto &I : Child->bases()) {
14800b57cec5SDimitry Andric     if (I.getType()->getAsCXXRecordDecl() == Base)
14810b57cec5SDimitry Andric       return true;
14820b57cec5SDimitry Andric   }
14830b57cec5SDimitry Andric 
14840b57cec5SDimitry Andric   return false;
14850b57cec5SDimitry Andric }
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric static RegionOffset calculateOffset(const MemRegion *R) {
14880b57cec5SDimitry Andric   const MemRegion *SymbolicOffsetBase = nullptr;
14890b57cec5SDimitry Andric   int64_t Offset = 0;
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric   while (true) {
14920b57cec5SDimitry Andric     switch (R->getKind()) {
14930b57cec5SDimitry Andric     case MemRegion::CodeSpaceRegionKind:
14940b57cec5SDimitry Andric     case MemRegion::StackLocalsSpaceRegionKind:
14950b57cec5SDimitry Andric     case MemRegion::StackArgumentsSpaceRegionKind:
14960b57cec5SDimitry Andric     case MemRegion::HeapSpaceRegionKind:
14970b57cec5SDimitry Andric     case MemRegion::UnknownSpaceRegionKind:
14980b57cec5SDimitry Andric     case MemRegion::StaticGlobalSpaceRegionKind:
14990b57cec5SDimitry Andric     case MemRegion::GlobalInternalSpaceRegionKind:
15000b57cec5SDimitry Andric     case MemRegion::GlobalSystemSpaceRegionKind:
15010b57cec5SDimitry Andric     case MemRegion::GlobalImmutableSpaceRegionKind:
15020b57cec5SDimitry Andric       // Stores can bind directly to a region space to set a default value.
15030b57cec5SDimitry Andric       assert(Offset == 0 && !SymbolicOffsetBase);
15040b57cec5SDimitry Andric       goto Finish;
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric     case MemRegion::FunctionCodeRegionKind:
15070b57cec5SDimitry Andric     case MemRegion::BlockCodeRegionKind:
15080b57cec5SDimitry Andric     case MemRegion::BlockDataRegionKind:
15090b57cec5SDimitry Andric       // These will never have bindings, but may end up having values requested
15100b57cec5SDimitry Andric       // if the user does some strange casting.
15110b57cec5SDimitry Andric       if (Offset != 0)
15120b57cec5SDimitry Andric         SymbolicOffsetBase = R;
15130b57cec5SDimitry Andric       goto Finish;
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric     case MemRegion::SymbolicRegionKind:
15160b57cec5SDimitry Andric     case MemRegion::AllocaRegionKind:
15170b57cec5SDimitry Andric     case MemRegion::CompoundLiteralRegionKind:
15180b57cec5SDimitry Andric     case MemRegion::CXXThisRegionKind:
15190b57cec5SDimitry Andric     case MemRegion::StringRegionKind:
15200b57cec5SDimitry Andric     case MemRegion::ObjCStringRegionKind:
15215ffd83dbSDimitry Andric     case MemRegion::NonParamVarRegionKind:
15225ffd83dbSDimitry Andric     case MemRegion::ParamVarRegionKind:
15230b57cec5SDimitry Andric     case MemRegion::CXXTempObjectRegionKind:
152406c3fb27SDimitry Andric     case MemRegion::CXXLifetimeExtendedObjectRegionKind:
15250b57cec5SDimitry Andric       // Usual base regions.
15260b57cec5SDimitry Andric       goto Finish;
15270b57cec5SDimitry Andric 
15280b57cec5SDimitry Andric     case MemRegion::ObjCIvarRegionKind:
15290b57cec5SDimitry Andric       // This is a little strange, but it's a compromise between
15300b57cec5SDimitry Andric       // ObjCIvarRegions having unknown compile-time offsets (when using the
15310b57cec5SDimitry Andric       // non-fragile runtime) and yet still being distinct, non-overlapping
15320b57cec5SDimitry Andric       // regions. Thus we treat them as "like" base regions for the purposes
15330b57cec5SDimitry Andric       // of computing offsets.
15340b57cec5SDimitry Andric       goto Finish;
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric     case MemRegion::CXXBaseObjectRegionKind: {
15370b57cec5SDimitry Andric       const auto *BOR = cast<CXXBaseObjectRegion>(R);
15380b57cec5SDimitry Andric       R = BOR->getSuperRegion();
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric       QualType Ty;
15410b57cec5SDimitry Andric       bool RootIsSymbolic = false;
15420b57cec5SDimitry Andric       if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
15430b57cec5SDimitry Andric         Ty = TVR->getDesugaredValueType(R->getContext());
15440b57cec5SDimitry Andric       } else if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
15450b57cec5SDimitry Andric         // If our base region is symbolic, we don't know what type it really is.
15460b57cec5SDimitry Andric         // Pretend the type of the symbol is the true dynamic type.
15470b57cec5SDimitry Andric         // (This will at least be self-consistent for the life of the symbol.)
1548bdd1243dSDimitry Andric         Ty = SR->getPointeeStaticType();
15490b57cec5SDimitry Andric         RootIsSymbolic = true;
15500b57cec5SDimitry Andric       }
15510b57cec5SDimitry Andric 
15520b57cec5SDimitry Andric       const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
15530b57cec5SDimitry Andric       if (!Child) {
15540b57cec5SDimitry Andric         // We cannot compute the offset of the base class.
15550b57cec5SDimitry Andric         SymbolicOffsetBase = R;
15560b57cec5SDimitry Andric       } else {
15570b57cec5SDimitry Andric         if (RootIsSymbolic) {
15580b57cec5SDimitry Andric           // Base layers on symbolic regions may not be type-correct.
15590b57cec5SDimitry Andric           // Double-check the inheritance here, and revert to a symbolic offset
15600b57cec5SDimitry Andric           // if it's invalid (e.g. due to a reinterpret_cast).
15610b57cec5SDimitry Andric           if (BOR->isVirtual()) {
15620b57cec5SDimitry Andric             if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
15630b57cec5SDimitry Andric               SymbolicOffsetBase = R;
15640b57cec5SDimitry Andric           } else {
15650b57cec5SDimitry Andric             if (!isImmediateBase(Child, BOR->getDecl()))
15660b57cec5SDimitry Andric               SymbolicOffsetBase = R;
15670b57cec5SDimitry Andric           }
15680b57cec5SDimitry Andric         }
15690b57cec5SDimitry Andric       }
15700b57cec5SDimitry Andric 
15710b57cec5SDimitry Andric       // Don't bother calculating precise offsets if we already have a
15720b57cec5SDimitry Andric       // symbolic offset somewhere in the chain.
15730b57cec5SDimitry Andric       if (SymbolicOffsetBase)
15740b57cec5SDimitry Andric         continue;
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric       CharUnits BaseOffset;
15770b57cec5SDimitry Andric       const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
15780b57cec5SDimitry Andric       if (BOR->isVirtual())
15790b57cec5SDimitry Andric         BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
15800b57cec5SDimitry Andric       else
15810b57cec5SDimitry Andric         BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
15820b57cec5SDimitry Andric 
15830b57cec5SDimitry Andric       // The base offset is in chars, not in bits.
15840b57cec5SDimitry Andric       Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
15850b57cec5SDimitry Andric       break;
15860b57cec5SDimitry Andric     }
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric     case MemRegion::CXXDerivedObjectRegionKind: {
15890b57cec5SDimitry Andric       // TODO: Store the base type in the CXXDerivedObjectRegion and use it.
15900b57cec5SDimitry Andric       goto Finish;
15910b57cec5SDimitry Andric     }
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric     case MemRegion::ElementRegionKind: {
15940b57cec5SDimitry Andric       const auto *ER = cast<ElementRegion>(R);
15950b57cec5SDimitry Andric       R = ER->getSuperRegion();
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric       QualType EleTy = ER->getValueType();
15980b57cec5SDimitry Andric       if (EleTy->isIncompleteType()) {
15990b57cec5SDimitry Andric         // We cannot compute the offset of the base class.
16000b57cec5SDimitry Andric         SymbolicOffsetBase = R;
16010b57cec5SDimitry Andric         continue;
16020b57cec5SDimitry Andric       }
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric       SVal Index = ER->getIndex();
1605bdd1243dSDimitry Andric       if (std::optional<nonloc::ConcreteInt> CI =
16060b57cec5SDimitry Andric               Index.getAs<nonloc::ConcreteInt>()) {
16070b57cec5SDimitry Andric         // Don't bother calculating precise offsets if we already have a
16080b57cec5SDimitry Andric         // symbolic offset somewhere in the chain.
16090b57cec5SDimitry Andric         if (SymbolicOffsetBase)
16100b57cec5SDimitry Andric           continue;
16110b57cec5SDimitry Andric 
16120b57cec5SDimitry Andric         int64_t i = CI->getValue().getSExtValue();
16130b57cec5SDimitry Andric         // This type size is in bits.
16140b57cec5SDimitry Andric         Offset += i * R->getContext().getTypeSize(EleTy);
16150b57cec5SDimitry Andric       } else {
16160b57cec5SDimitry Andric         // We cannot compute offset for non-concrete index.
16170b57cec5SDimitry Andric         SymbolicOffsetBase = R;
16180b57cec5SDimitry Andric       }
16190b57cec5SDimitry Andric       break;
16200b57cec5SDimitry Andric     }
16210b57cec5SDimitry Andric     case MemRegion::FieldRegionKind: {
16220b57cec5SDimitry Andric       const auto *FR = cast<FieldRegion>(R);
16230b57cec5SDimitry Andric       R = FR->getSuperRegion();
1624a7dea167SDimitry Andric       assert(R);
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric       const RecordDecl *RD = FR->getDecl()->getParent();
16270b57cec5SDimitry Andric       if (RD->isUnion() || !RD->isCompleteDefinition()) {
16280b57cec5SDimitry Andric         // We cannot compute offset for incomplete type.
16290b57cec5SDimitry Andric         // For unions, we could treat everything as offset 0, but we'd rather
16300b57cec5SDimitry Andric         // treat each field as a symbolic offset so they aren't stored on top
16310b57cec5SDimitry Andric         // of each other, since we depend on things in typed regions actually
16320b57cec5SDimitry Andric         // matching their types.
16330b57cec5SDimitry Andric         SymbolicOffsetBase = R;
16340b57cec5SDimitry Andric       }
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric       // Don't bother calculating precise offsets if we already have a
16370b57cec5SDimitry Andric       // symbolic offset somewhere in the chain.
16380b57cec5SDimitry Andric       if (SymbolicOffsetBase)
16390b57cec5SDimitry Andric         continue;
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric       // Get the field number.
16420b57cec5SDimitry Andric       unsigned idx = 0;
16430b57cec5SDimitry Andric       for (RecordDecl::field_iterator FI = RD->field_begin(),
16440b57cec5SDimitry Andric              FE = RD->field_end(); FI != FE; ++FI, ++idx) {
16450b57cec5SDimitry Andric         if (FR->getDecl() == *FI)
16460b57cec5SDimitry Andric           break;
16470b57cec5SDimitry Andric       }
16480b57cec5SDimitry Andric       const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
16490b57cec5SDimitry Andric       // This is offset in bits.
16500b57cec5SDimitry Andric       Offset += Layout.getFieldOffset(idx);
16510b57cec5SDimitry Andric       break;
16520b57cec5SDimitry Andric     }
16530b57cec5SDimitry Andric     }
16540b57cec5SDimitry Andric   }
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric  Finish:
16570b57cec5SDimitry Andric   if (SymbolicOffsetBase)
16580b57cec5SDimitry Andric     return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
16590b57cec5SDimitry Andric   return RegionOffset(R, Offset);
16600b57cec5SDimitry Andric }
16610b57cec5SDimitry Andric 
16620b57cec5SDimitry Andric RegionOffset MemRegion::getAsOffset() const {
16630b57cec5SDimitry Andric   if (!cachedOffset)
16640b57cec5SDimitry Andric     cachedOffset = calculateOffset(this);
16650b57cec5SDimitry Andric   return *cachedOffset;
16660b57cec5SDimitry Andric }
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16690b57cec5SDimitry Andric // BlockDataRegion
16700b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric std::pair<const VarRegion *, const VarRegion *>
16730b57cec5SDimitry Andric BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
16745ffd83dbSDimitry Andric   MemRegionManager &MemMgr = getMemRegionManager();
16750b57cec5SDimitry Andric   const VarRegion *VR = nullptr;
16760b57cec5SDimitry Andric   const VarRegion *OriginalVR = nullptr;
16770b57cec5SDimitry Andric 
16780b57cec5SDimitry Andric   if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
16795ffd83dbSDimitry Andric     VR = MemMgr.getNonParamVarRegion(VD, this);
16800b57cec5SDimitry Andric     OriginalVR = MemMgr.getVarRegion(VD, LC);
16810b57cec5SDimitry Andric   }
16820b57cec5SDimitry Andric   else {
16830b57cec5SDimitry Andric     if (LC) {
16840b57cec5SDimitry Andric       VR = MemMgr.getVarRegion(VD, LC);
16850b57cec5SDimitry Andric       OriginalVR = VR;
16860b57cec5SDimitry Andric     }
16870b57cec5SDimitry Andric     else {
16885ffd83dbSDimitry Andric       VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion());
16890b57cec5SDimitry Andric       OriginalVR = MemMgr.getVarRegion(VD, LC);
16900b57cec5SDimitry Andric     }
16910b57cec5SDimitry Andric   }
16920b57cec5SDimitry Andric   return std::make_pair(VR, OriginalVR);
16930b57cec5SDimitry Andric }
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric void BlockDataRegion::LazyInitializeReferencedVars() {
16960b57cec5SDimitry Andric   if (ReferencedVars)
16970b57cec5SDimitry Andric     return;
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric   AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
17000b57cec5SDimitry Andric   const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
17010b57cec5SDimitry Andric   auto NumBlockVars =
17020b57cec5SDimitry Andric       std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
17030b57cec5SDimitry Andric 
17040b57cec5SDimitry Andric   if (NumBlockVars == 0) {
17050b57cec5SDimitry Andric     ReferencedVars = (void*) 0x1;
17060b57cec5SDimitry Andric     return;
17070b57cec5SDimitry Andric   }
17080b57cec5SDimitry Andric 
17095ffd83dbSDimitry Andric   MemRegionManager &MemMgr = getMemRegionManager();
17100b57cec5SDimitry Andric   llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
17110b57cec5SDimitry Andric   BumpVectorContext BC(A);
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric   using VarVec = BumpVector<const MemRegion *>;
17140b57cec5SDimitry Andric 
171506c3fb27SDimitry Andric   auto *BV = new (A) VarVec(BC, NumBlockVars);
171606c3fb27SDimitry Andric   auto *BVOriginal = new (A) VarVec(BC, NumBlockVars);
17170b57cec5SDimitry Andric 
17180b57cec5SDimitry Andric   for (const auto *VD : ReferencedBlockVars) {
17190b57cec5SDimitry Andric     const VarRegion *VR = nullptr;
17200b57cec5SDimitry Andric     const VarRegion *OriginalVR = nullptr;
17210b57cec5SDimitry Andric     std::tie(VR, OriginalVR) = getCaptureRegions(VD);
17220b57cec5SDimitry Andric     assert(VR);
17230b57cec5SDimitry Andric     assert(OriginalVR);
17240b57cec5SDimitry Andric     BV->push_back(VR, BC);
17250b57cec5SDimitry Andric     BVOriginal->push_back(OriginalVR, BC);
17260b57cec5SDimitry Andric   }
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   ReferencedVars = BV;
17290b57cec5SDimitry Andric   OriginalVars = BVOriginal;
17300b57cec5SDimitry Andric }
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric BlockDataRegion::referenced_vars_iterator
17330b57cec5SDimitry Andric BlockDataRegion::referenced_vars_begin() const {
17340b57cec5SDimitry Andric   const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
17350b57cec5SDimitry Andric 
17360b57cec5SDimitry Andric   auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   if (Vec == (void*) 0x1)
17390b57cec5SDimitry Andric     return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric   auto *VecOriginal =
17420b57cec5SDimitry Andric       static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
17430b57cec5SDimitry Andric 
17440b57cec5SDimitry Andric   return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
17450b57cec5SDimitry Andric                                                    VecOriginal->begin());
17460b57cec5SDimitry Andric }
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric BlockDataRegion::referenced_vars_iterator
17490b57cec5SDimitry Andric BlockDataRegion::referenced_vars_end() const {
17500b57cec5SDimitry Andric   const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric   auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric   if (Vec == (void*) 0x1)
17550b57cec5SDimitry Andric     return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric   auto *VecOriginal =
17580b57cec5SDimitry Andric       static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   return BlockDataRegion::referenced_vars_iterator(Vec->end(),
17610b57cec5SDimitry Andric                                                    VecOriginal->end());
17620b57cec5SDimitry Andric }
17630b57cec5SDimitry Andric 
176406c3fb27SDimitry Andric llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
176506c3fb27SDimitry Andric BlockDataRegion::referenced_vars() const {
176606c3fb27SDimitry Andric   return llvm::make_range(referenced_vars_begin(), referenced_vars_end());
176706c3fb27SDimitry Andric }
176806c3fb27SDimitry Andric 
17690b57cec5SDimitry Andric const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
177006c3fb27SDimitry Andric   for (const auto &I : referenced_vars()) {
17710b57cec5SDimitry Andric     if (I.getCapturedRegion() == R)
17720b57cec5SDimitry Andric       return I.getOriginalRegion();
17730b57cec5SDimitry Andric   }
17740b57cec5SDimitry Andric   return nullptr;
17750b57cec5SDimitry Andric }
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17780b57cec5SDimitry Andric // RegionAndSymbolInvalidationTraits
17790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
17820b57cec5SDimitry Andric                                                  InvalidationKinds IK) {
17830b57cec5SDimitry Andric   SymTraitsMap[Sym] |= IK;
17840b57cec5SDimitry Andric }
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
17870b57cec5SDimitry Andric                                                  InvalidationKinds IK) {
17880b57cec5SDimitry Andric   assert(MR);
17890b57cec5SDimitry Andric   if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
17900b57cec5SDimitry Andric     setTrait(SR->getSymbol(), IK);
17910b57cec5SDimitry Andric   else
17920b57cec5SDimitry Andric     MRTraitsMap[MR] |= IK;
17930b57cec5SDimitry Andric }
17940b57cec5SDimitry Andric 
17950b57cec5SDimitry Andric bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
17960b57cec5SDimitry Andric                                                  InvalidationKinds IK) const {
17970b57cec5SDimitry Andric   const_symbol_iterator I = SymTraitsMap.find(Sym);
17980b57cec5SDimitry Andric   if (I != SymTraitsMap.end())
17990b57cec5SDimitry Andric     return I->second & IK;
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric   return false;
18020b57cec5SDimitry Andric }
18030b57cec5SDimitry Andric 
18040b57cec5SDimitry Andric bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
18050b57cec5SDimitry Andric                                                  InvalidationKinds IK) const {
18060b57cec5SDimitry Andric   if (!MR)
18070b57cec5SDimitry Andric     return false;
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric   if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
18100b57cec5SDimitry Andric     return hasTrait(SR->getSymbol(), IK);
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   const_region_iterator I = MRTraitsMap.find(MR);
18130b57cec5SDimitry Andric   if (I != MRTraitsMap.end())
18140b57cec5SDimitry Andric     return I->second & IK;
18150b57cec5SDimitry Andric 
18160b57cec5SDimitry Andric   return false;
18170b57cec5SDimitry Andric }
1818