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