MemRegion.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768
  1. //===- MemRegion.cpp - Abstract memory regions for static analysis --------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines MemRegion and its subclasses. MemRegion defines a
  10. // partially-typed abstraction of memory useful for path-sensitive dataflow
  11. // analyses.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/Attr.h"
  17. #include "clang/AST/CharUnits.h"
  18. #include "clang/AST/Decl.h"
  19. #include "clang/AST/DeclCXX.h"
  20. #include "clang/AST/DeclObjC.h"
  21. #include "clang/AST/Expr.h"
  22. #include "clang/AST/PrettyPrinter.h"
  23. #include "clang/AST/RecordLayout.h"
  24. #include "clang/AST/Type.h"
  25. #include "clang/Analysis/AnalysisDeclContext.h"
  26. #include "clang/Analysis/Support/BumpVector.h"
  27. #include "clang/Basic/IdentifierTable.h"
  28. #include "clang/Basic/LLVM.h"
  29. #include "clang/Basic/SourceManager.h"
  30. #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
  31. #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
  32. #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
  33. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
  34. #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
  35. #include "llvm/ADT/APInt.h"
  36. #include "llvm/ADT/FoldingSet.h"
  37. #include "llvm/ADT/PointerUnion.h"
  38. #include "llvm/ADT/SmallString.h"
  39. #include "llvm/ADT/StringRef.h"
  40. #include "llvm/ADT/Twine.h"
  41. #include "llvm/Support/Allocator.h"
  42. #include "llvm/Support/Casting.h"
  43. #include "llvm/Support/CheckedArithmetic.h"
  44. #include "llvm/Support/Compiler.h"
  45. #include "llvm/Support/Debug.h"
  46. #include "llvm/Support/ErrorHandling.h"
  47. #include "llvm/Support/raw_ostream.h"
  48. #include <cassert>
  49. #include <cstdint>
  50. #include <functional>
  51. #include <iterator>
  52. #include <optional>
  53. #include <string>
  54. #include <tuple>
  55. #include <utility>
  56. using namespace clang;
  57. using namespace ento;
  58. #define DEBUG_TYPE "MemRegion"
  59. //===----------------------------------------------------------------------===//
  60. // MemRegion Construction.
  61. //===----------------------------------------------------------------------===//
  62. template <typename RegionTy, typename SuperTy, typename Arg1Ty>
  63. RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
  64. const SuperTy *superRegion) {
  65. llvm::FoldingSetNodeID ID;
  66. RegionTy::ProfileRegion(ID, arg1, superRegion);
  67. void *InsertPos;
  68. auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
  69. if (!R) {
  70. R = A.Allocate<RegionTy>();
  71. new (R) RegionTy(arg1, superRegion);
  72. Regions.InsertNode(R, InsertPos);
  73. }
  74. return R;
  75. }
  76. template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
  77. RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
  78. const SuperTy *superRegion) {
  79. llvm::FoldingSetNodeID ID;
  80. RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
  81. void *InsertPos;
  82. auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
  83. if (!R) {
  84. R = A.Allocate<RegionTy>();
  85. new (R) RegionTy(arg1, arg2, superRegion);
  86. Regions.InsertNode(R, InsertPos);
  87. }
  88. return R;
  89. }
  90. template <typename RegionTy, typename SuperTy,
  91. typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
  92. RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
  93. const Arg3Ty arg3,
  94. const SuperTy *superRegion) {
  95. llvm::FoldingSetNodeID ID;
  96. RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
  97. void *InsertPos;
  98. auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
  99. if (!R) {
  100. R = A.Allocate<RegionTy>();
  101. new (R) RegionTy(arg1, arg2, arg3, superRegion);
  102. Regions.InsertNode(R, InsertPos);
  103. }
  104. return R;
  105. }
  106. //===----------------------------------------------------------------------===//
  107. // Object destruction.
  108. //===----------------------------------------------------------------------===//
  109. MemRegion::~MemRegion() = default;
  110. // All regions and their data are BumpPtrAllocated. No need to call their
  111. // destructors.
  112. MemRegionManager::~MemRegionManager() = default;
  113. //===----------------------------------------------------------------------===//
  114. // Basic methods.
  115. //===----------------------------------------------------------------------===//
  116. bool SubRegion::isSubRegionOf(const MemRegion* R) const {
  117. const MemRegion* r = this;
  118. do {
  119. if (r == R)
  120. return true;
  121. if (const auto *sr = dyn_cast<SubRegion>(r))
  122. r = sr->getSuperRegion();
  123. else
  124. break;
  125. } while (r != nullptr);
  126. return false;
  127. }
  128. MemRegionManager &SubRegion::getMemRegionManager() const {
  129. const SubRegion* r = this;
  130. do {
  131. const MemRegion *superRegion = r->getSuperRegion();
  132. if (const auto *sr = dyn_cast<SubRegion>(superRegion)) {
  133. r = sr;
  134. continue;
  135. }
  136. return superRegion->getMemRegionManager();
  137. } while (true);
  138. }
  139. const StackFrameContext *VarRegion::getStackFrame() const {
  140. const auto *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
  141. return SSR ? SSR->getStackFrame() : nullptr;
  142. }
  143. ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
  144. : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {
  145. assert(IVD);
  146. }
  147. const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { return IVD; }
  148. QualType ObjCIvarRegion::getValueType() const {
  149. return getDecl()->getType();
  150. }
  151. QualType CXXBaseObjectRegion::getValueType() const {
  152. return QualType(getDecl()->getTypeForDecl(), 0);
  153. }
  154. QualType CXXDerivedObjectRegion::getValueType() const {
  155. return QualType(getDecl()->getTypeForDecl(), 0);
  156. }
  157. QualType ParamVarRegion::getValueType() const {
  158. assert(getDecl() &&
  159. "`ParamVarRegion` support functions without `Decl` not implemented"
  160. " yet.");
  161. return getDecl()->getType();
  162. }
  163. const ParmVarDecl *ParamVarRegion::getDecl() const {
  164. const Decl *D = getStackFrame()->getDecl();
  165. if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
  166. assert(Index < FD->param_size());
  167. return FD->parameters()[Index];
  168. } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
  169. assert(Index < BD->param_size());
  170. return BD->parameters()[Index];
  171. } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
  172. assert(Index < MD->param_size());
  173. return MD->parameters()[Index];
  174. } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
  175. assert(Index < CD->param_size());
  176. return CD->parameters()[Index];
  177. } else {
  178. llvm_unreachable("Unexpected Decl kind!");
  179. }
  180. }
  181. //===----------------------------------------------------------------------===//
  182. // FoldingSet profiling.
  183. //===----------------------------------------------------------------------===//
  184. void MemSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  185. ID.AddInteger(static_cast<unsigned>(getKind()));
  186. }
  187. void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  188. ID.AddInteger(static_cast<unsigned>(getKind()));
  189. ID.AddPointer(getStackFrame());
  190. }
  191. void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  192. ID.AddInteger(static_cast<unsigned>(getKind()));
  193. ID.AddPointer(getCodeRegion());
  194. }
  195. void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  196. const StringLiteral *Str,
  197. const MemRegion *superRegion) {
  198. ID.AddInteger(static_cast<unsigned>(StringRegionKind));
  199. ID.AddPointer(Str);
  200. ID.AddPointer(superRegion);
  201. }
  202. void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  203. const ObjCStringLiteral *Str,
  204. const MemRegion *superRegion) {
  205. ID.AddInteger(static_cast<unsigned>(ObjCStringRegionKind));
  206. ID.AddPointer(Str);
  207. ID.AddPointer(superRegion);
  208. }
  209. void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  210. const Expr *Ex, unsigned cnt,
  211. const MemRegion *superRegion) {
  212. ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
  213. ID.AddPointer(Ex);
  214. ID.AddInteger(cnt);
  215. ID.AddPointer(superRegion);
  216. }
  217. void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  218. ProfileRegion(ID, Ex, Cnt, superRegion);
  219. }
  220. void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  221. CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
  222. }
  223. void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  224. const CompoundLiteralExpr *CL,
  225. const MemRegion* superRegion) {
  226. ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
  227. ID.AddPointer(CL);
  228. ID.AddPointer(superRegion);
  229. }
  230. void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  231. const PointerType *PT,
  232. const MemRegion *sRegion) {
  233. ID.AddInteger(static_cast<unsigned>(CXXThisRegionKind));
  234. ID.AddPointer(PT);
  235. ID.AddPointer(sRegion);
  236. }
  237. void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  238. CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
  239. }
  240. void FieldRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  241. ProfileRegion(ID, getDecl(), superRegion);
  242. }
  243. void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  244. const ObjCIvarDecl *ivd,
  245. const MemRegion* superRegion) {
  246. ID.AddInteger(static_cast<unsigned>(ObjCIvarRegionKind));
  247. ID.AddPointer(ivd);
  248. ID.AddPointer(superRegion);
  249. }
  250. void ObjCIvarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  251. ProfileRegion(ID, getDecl(), superRegion);
  252. }
  253. void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  254. const VarDecl *VD,
  255. const MemRegion *superRegion) {
  256. ID.AddInteger(static_cast<unsigned>(NonParamVarRegionKind));
  257. ID.AddPointer(VD);
  258. ID.AddPointer(superRegion);
  259. }
  260. void NonParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  261. ProfileRegion(ID, getDecl(), superRegion);
  262. }
  263. void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
  264. unsigned Idx, const MemRegion *SReg) {
  265. ID.AddInteger(static_cast<unsigned>(ParamVarRegionKind));
  266. ID.AddPointer(OE);
  267. ID.AddInteger(Idx);
  268. ID.AddPointer(SReg);
  269. }
  270. void ParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  271. ProfileRegion(ID, getOriginExpr(), getIndex(), superRegion);
  272. }
  273. void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
  274. const MemRegion *sreg) {
  275. ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
  276. ID.Add(sym);
  277. ID.AddPointer(sreg);
  278. }
  279. void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  280. SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
  281. }
  282. void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  283. QualType ElementType, SVal Idx,
  284. const MemRegion* superRegion) {
  285. ID.AddInteger(MemRegion::ElementRegionKind);
  286. ID.Add(ElementType);
  287. ID.AddPointer(superRegion);
  288. Idx.Profile(ID);
  289. }
  290. void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  291. ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
  292. }
  293. void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  294. const NamedDecl *FD,
  295. const MemRegion*) {
  296. ID.AddInteger(MemRegion::FunctionCodeRegionKind);
  297. ID.AddPointer(FD);
  298. }
  299. void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  300. FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
  301. }
  302. void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  303. const BlockDecl *BD, CanQualType,
  304. const AnalysisDeclContext *AC,
  305. const MemRegion*) {
  306. ID.AddInteger(MemRegion::BlockCodeRegionKind);
  307. ID.AddPointer(BD);
  308. }
  309. void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  310. BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
  311. }
  312. void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  313. const BlockCodeRegion *BC,
  314. const LocationContext *LC,
  315. unsigned BlkCount,
  316. const MemRegion *sReg) {
  317. ID.AddInteger(MemRegion::BlockDataRegionKind);
  318. ID.AddPointer(BC);
  319. ID.AddPointer(LC);
  320. ID.AddInteger(BlkCount);
  321. ID.AddPointer(sReg);
  322. }
  323. void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  324. BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
  325. }
  326. void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  327. Expr const *Ex,
  328. const MemRegion *sReg) {
  329. ID.AddPointer(Ex);
  330. ID.AddPointer(sReg);
  331. }
  332. void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  333. ProfileRegion(ID, Ex, getSuperRegion());
  334. }
  335. void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  336. const CXXRecordDecl *RD,
  337. bool IsVirtual,
  338. const MemRegion *SReg) {
  339. ID.AddPointer(RD);
  340. ID.AddBoolean(IsVirtual);
  341. ID.AddPointer(SReg);
  342. }
  343. void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  344. ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
  345. }
  346. void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  347. const CXXRecordDecl *RD,
  348. const MemRegion *SReg) {
  349. ID.AddPointer(RD);
  350. ID.AddPointer(SReg);
  351. }
  352. void CXXDerivedObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  353. ProfileRegion(ID, getDecl(), superRegion);
  354. }
  355. //===----------------------------------------------------------------------===//
  356. // Region anchors.
  357. //===----------------------------------------------------------------------===//
  358. void GlobalsSpaceRegion::anchor() {}
  359. void NonStaticGlobalSpaceRegion::anchor() {}
  360. void StackSpaceRegion::anchor() {}
  361. void TypedRegion::anchor() {}
  362. void TypedValueRegion::anchor() {}
  363. void CodeTextRegion::anchor() {}
  364. void SubRegion::anchor() {}
  365. //===----------------------------------------------------------------------===//
  366. // Region pretty-printing.
  367. //===----------------------------------------------------------------------===//
  368. LLVM_DUMP_METHOD void MemRegion::dump() const {
  369. dumpToStream(llvm::errs());
  370. }
  371. std::string MemRegion::getString() const {
  372. std::string s;
  373. llvm::raw_string_ostream os(s);
  374. dumpToStream(os);
  375. return s;
  376. }
  377. void MemRegion::dumpToStream(raw_ostream &os) const {
  378. os << "<Unknown Region>";
  379. }
  380. void AllocaRegion::dumpToStream(raw_ostream &os) const {
  381. os << "alloca{S" << Ex->getID(getContext()) << ',' << Cnt << '}';
  382. }
  383. void FunctionCodeRegion::dumpToStream(raw_ostream &os) const {
  384. os << "code{" << getDecl()->getDeclName().getAsString() << '}';
  385. }
  386. void BlockCodeRegion::dumpToStream(raw_ostream &os) const {
  387. os << "block_code{" << static_cast<const void *>(this) << '}';
  388. }
  389. void BlockDataRegion::dumpToStream(raw_ostream &os) const {
  390. os << "block_data{" << BC;
  391. os << "; ";
  392. for (BlockDataRegion::referenced_vars_iterator
  393. I = referenced_vars_begin(),
  394. E = referenced_vars_end(); I != E; ++I)
  395. os << "(" << I.getCapturedRegion() << "<-" <<
  396. I.getOriginalRegion() << ") ";
  397. os << '}';
  398. }
  399. void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
  400. // FIXME: More elaborate pretty-printing.
  401. os << "{ S" << CL->getID(getContext()) << " }";
  402. }
  403. void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
  404. os << "temp_object{" << getValueType() << ", "
  405. << "S" << Ex->getID(getContext()) << '}';
  406. }
  407. void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
  408. os << "Base{" << superRegion << ',' << getDecl()->getName() << '}';
  409. }
  410. void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {
  411. os << "Derived{" << superRegion << ',' << getDecl()->getName() << '}';
  412. }
  413. void CXXThisRegion::dumpToStream(raw_ostream &os) const {
  414. os << "this";
  415. }
  416. void ElementRegion::dumpToStream(raw_ostream &os) const {
  417. os << "Element{" << superRegion << ',' << Index << ',' << getElementType()
  418. << '}';
  419. }
  420. void FieldRegion::dumpToStream(raw_ostream &os) const {
  421. os << superRegion << "." << *getDecl();
  422. }
  423. void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
  424. os << "Ivar{" << superRegion << ',' << *getDecl() << '}';
  425. }
  426. void StringRegion::dumpToStream(raw_ostream &os) const {
  427. assert(Str != nullptr && "Expecting non-null StringLiteral");
  428. Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
  429. }
  430. void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
  431. assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
  432. Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
  433. }
  434. void SymbolicRegion::dumpToStream(raw_ostream &os) const {
  435. if (isa<HeapSpaceRegion>(getSuperRegion()))
  436. os << "Heap";
  437. os << "SymRegion{" << sym << '}';
  438. }
  439. void NonParamVarRegion::dumpToStream(raw_ostream &os) const {
  440. if (const IdentifierInfo *ID = VD->getIdentifier())
  441. os << ID->getName();
  442. else
  443. os << "NonParamVarRegion{D" << VD->getID() << '}';
  444. }
  445. LLVM_DUMP_METHOD void RegionRawOffset::dump() const {
  446. dumpToStream(llvm::errs());
  447. }
  448. void RegionRawOffset::dumpToStream(raw_ostream &os) const {
  449. os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
  450. }
  451. void CodeSpaceRegion::dumpToStream(raw_ostream &os) const {
  452. os << "CodeSpaceRegion";
  453. }
  454. void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
  455. os << "StaticGlobalsMemSpace{" << CR << '}';
  456. }
  457. void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
  458. os << "GlobalInternalSpaceRegion";
  459. }
  460. void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
  461. os << "GlobalSystemSpaceRegion";
  462. }
  463. void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
  464. os << "GlobalImmutableSpaceRegion";
  465. }
  466. void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
  467. os << "HeapSpaceRegion";
  468. }
  469. void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
  470. os << "UnknownSpaceRegion";
  471. }
  472. void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
  473. os << "StackArgumentsSpaceRegion";
  474. }
  475. void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
  476. os << "StackLocalsSpaceRegion";
  477. }
  478. void ParamVarRegion::dumpToStream(raw_ostream &os) const {
  479. const ParmVarDecl *PVD = getDecl();
  480. assert(PVD &&
  481. "`ParamVarRegion` support functions without `Decl` not implemented"
  482. " yet.");
  483. if (const IdentifierInfo *ID = PVD->getIdentifier()) {
  484. os << ID->getName();
  485. } else {
  486. os << "ParamVarRegion{P" << PVD->getID() << '}';
  487. }
  488. }
  489. bool MemRegion::canPrintPretty() const {
  490. return canPrintPrettyAsExpr();
  491. }
  492. bool MemRegion::canPrintPrettyAsExpr() const {
  493. return false;
  494. }
  495. void MemRegion::printPretty(raw_ostream &os) const {
  496. assert(canPrintPretty() && "This region cannot be printed pretty.");
  497. os << "'";
  498. printPrettyAsExpr(os);
  499. os << "'";
  500. }
  501. void MemRegion::printPrettyAsExpr(raw_ostream &) const {
  502. llvm_unreachable("This region cannot be printed pretty.");
  503. }
  504. bool NonParamVarRegion::canPrintPrettyAsExpr() const { return true; }
  505. void NonParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
  506. os << getDecl()->getName();
  507. }
  508. bool ParamVarRegion::canPrintPrettyAsExpr() const { return true; }
  509. void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
  510. assert(getDecl() &&
  511. "`ParamVarRegion` support functions without `Decl` not implemented"
  512. " yet.");
  513. os << getDecl()->getName();
  514. }
  515. bool ObjCIvarRegion::canPrintPrettyAsExpr() const {
  516. return true;
  517. }
  518. void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
  519. os << getDecl()->getName();
  520. }
  521. bool FieldRegion::canPrintPretty() const {
  522. return true;
  523. }
  524. bool FieldRegion::canPrintPrettyAsExpr() const {
  525. return superRegion->canPrintPrettyAsExpr();
  526. }
  527. void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
  528. assert(canPrintPrettyAsExpr());
  529. superRegion->printPrettyAsExpr(os);
  530. os << "." << getDecl()->getName();
  531. }
  532. void FieldRegion::printPretty(raw_ostream &os) const {
  533. if (canPrintPrettyAsExpr()) {
  534. os << "\'";
  535. printPrettyAsExpr(os);
  536. os << "'";
  537. } else {
  538. os << "field " << "\'" << getDecl()->getName() << "'";
  539. }
  540. }
  541. bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
  542. return superRegion->canPrintPrettyAsExpr();
  543. }
  544. void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
  545. superRegion->printPrettyAsExpr(os);
  546. }
  547. bool CXXDerivedObjectRegion::canPrintPrettyAsExpr() const {
  548. return superRegion->canPrintPrettyAsExpr();
  549. }
  550. void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
  551. superRegion->printPrettyAsExpr(os);
  552. }
  553. std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
  554. std::string VariableName;
  555. std::string ArrayIndices;
  556. const MemRegion *R = this;
  557. SmallString<50> buf;
  558. llvm::raw_svector_ostream os(buf);
  559. // Obtain array indices to add them to the variable name.
  560. const ElementRegion *ER = nullptr;
  561. while ((ER = R->getAs<ElementRegion>())) {
  562. // Index is a ConcreteInt.
  563. if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
  564. llvm::SmallString<2> Idx;
  565. CI->getValue().toString(Idx);
  566. ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
  567. }
  568. // If not a ConcreteInt, try to obtain the variable
  569. // name by calling 'getDescriptiveName' recursively.
  570. else {
  571. std::string Idx = ER->getDescriptiveName(false);
  572. if (!Idx.empty()) {
  573. ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
  574. }
  575. }
  576. R = ER->getSuperRegion();
  577. }
  578. // Get variable name.
  579. if (R && R->canPrintPrettyAsExpr()) {
  580. R->printPrettyAsExpr(os);
  581. if (UseQuotes)
  582. return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
  583. else
  584. return (llvm::Twine(os.str()) + ArrayIndices).str();
  585. }
  586. return VariableName;
  587. }
  588. SourceRange MemRegion::sourceRange() const {
  589. const auto *const VR = dyn_cast<VarRegion>(this->getBaseRegion());
  590. const auto *const FR = dyn_cast<FieldRegion>(this);
  591. // Check for more specific regions first.
  592. // FieldRegion
  593. if (FR) {
  594. return FR->getDecl()->getSourceRange();
  595. }
  596. // VarRegion
  597. else if (VR) {
  598. return VR->getDecl()->getSourceRange();
  599. }
  600. // Return invalid source range (can be checked by client).
  601. else
  602. return {};
  603. }
  604. //===----------------------------------------------------------------------===//
  605. // MemRegionManager methods.
  606. //===----------------------------------------------------------------------===//
  607. DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
  608. SValBuilder &SVB) const {
  609. const auto *SR = cast<SubRegion>(MR);
  610. SymbolManager &SymMgr = SVB.getSymbolManager();
  611. switch (SR->getKind()) {
  612. case MemRegion::AllocaRegionKind:
  613. case MemRegion::SymbolicRegionKind:
  614. return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
  615. case MemRegion::StringRegionKind:
  616. return SVB.makeIntVal(
  617. cast<StringRegion>(SR)->getStringLiteral()->getByteLength() + 1,
  618. SVB.getArrayIndexType());
  619. case MemRegion::CompoundLiteralRegionKind:
  620. case MemRegion::CXXBaseObjectRegionKind:
  621. case MemRegion::CXXDerivedObjectRegionKind:
  622. case MemRegion::CXXTempObjectRegionKind:
  623. case MemRegion::CXXThisRegionKind:
  624. case MemRegion::ObjCIvarRegionKind:
  625. case MemRegion::NonParamVarRegionKind:
  626. case MemRegion::ParamVarRegionKind:
  627. case MemRegion::ElementRegionKind:
  628. case MemRegion::ObjCStringRegionKind: {
  629. QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
  630. if (isa<VariableArrayType>(Ty))
  631. return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
  632. if (Ty->isIncompleteType())
  633. return UnknownVal();
  634. return getElementExtent(Ty, SVB);
  635. }
  636. case MemRegion::FieldRegionKind: {
  637. // Force callers to deal with bitfields explicitly.
  638. if (cast<FieldRegion>(SR)->getDecl()->isBitField())
  639. return UnknownVal();
  640. QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
  641. const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
  642. // We currently don't model flexible array members (FAMs), which are:
  643. // - int array[]; of IncompleteArrayType
  644. // - int array[0]; of ConstantArrayType with size 0
  645. // - int array[1]; of ConstantArrayType with size 1 (*)
  646. // (*): Consider single element array object members as FAM candidates only
  647. // if the consider-single-element-arrays-as-flexible-array-members
  648. // analyzer option is true.
  649. // https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
  650. const auto isFlexibleArrayMemberCandidate = [this,
  651. &SVB](QualType Ty) -> bool {
  652. const ArrayType *AT = Ctx.getAsArrayType(Ty);
  653. if (!AT)
  654. return false;
  655. if (isa<IncompleteArrayType>(AT))
  656. return true;
  657. if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
  658. using FAMKind = LangOptions::StrictFlexArraysLevelKind;
  659. const FAMKind StrictFlexArraysLevel =
  660. Ctx.getLangOpts().getStrictFlexArraysLevel();
  661. const AnalyzerOptions &Opts = SVB.getAnalyzerOptions();
  662. const llvm::APInt &Size = CAT->getSize();
  663. if (StrictFlexArraysLevel <= FAMKind::ZeroOrIncomplete && Size.isZero())
  664. return true;
  665. // The "-fstrict-flex-arrays" should have precedence over
  666. // consider-single-element-arrays-as-flexible-array-members
  667. // analyzer-config when checking single element arrays.
  668. if (StrictFlexArraysLevel == FAMKind::Default) {
  669. // FIXME: After clang-17 released, we should remove this branch.
  670. if (Opts.ShouldConsiderSingleElementArraysAsFlexibleArrayMembers &&
  671. Size.isOne())
  672. return true;
  673. } else {
  674. // -fstrict-flex-arrays was specified, since it's not the default, so
  675. // ignore analyzer-config.
  676. if (StrictFlexArraysLevel <= FAMKind::OneZeroOrIncomplete &&
  677. Size.isOne())
  678. return true;
  679. }
  680. }
  681. return false;
  682. };
  683. if (isFlexibleArrayMemberCandidate(Ty))
  684. return UnknownVal();
  685. return Size;
  686. }
  687. // FIXME: The following are being used in 'SimpleSValBuilder' and in
  688. // 'ArrayBoundChecker::checkLocation' because there is no symbol to
  689. // represent the regions more appropriately.
  690. case MemRegion::BlockDataRegionKind:
  691. case MemRegion::BlockCodeRegionKind:
  692. case MemRegion::FunctionCodeRegionKind:
  693. return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
  694. default:
  695. llvm_unreachable("Unhandled region");
  696. }
  697. }
  698. template <typename REG>
  699. const REG *MemRegionManager::LazyAllocate(REG*& region) {
  700. if (!region) {
  701. region = A.Allocate<REG>();
  702. new (region) REG(*this);
  703. }
  704. return region;
  705. }
  706. template <typename REG, typename ARG>
  707. const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
  708. if (!region) {
  709. region = A.Allocate<REG>();
  710. new (region) REG(this, a);
  711. }
  712. return region;
  713. }
  714. const StackLocalsSpaceRegion*
  715. MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
  716. assert(STC);
  717. StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
  718. if (R)
  719. return R;
  720. R = A.Allocate<StackLocalsSpaceRegion>();
  721. new (R) StackLocalsSpaceRegion(*this, STC);
  722. return R;
  723. }
  724. const StackArgumentsSpaceRegion *
  725. MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
  726. assert(STC);
  727. StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
  728. if (R)
  729. return R;
  730. R = A.Allocate<StackArgumentsSpaceRegion>();
  731. new (R) StackArgumentsSpaceRegion(*this, STC);
  732. return R;
  733. }
  734. const GlobalsSpaceRegion
  735. *MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
  736. const CodeTextRegion *CR) {
  737. if (!CR) {
  738. if (K == MemRegion::GlobalSystemSpaceRegionKind)
  739. return LazyAllocate(SystemGlobals);
  740. if (K == MemRegion::GlobalImmutableSpaceRegionKind)
  741. return LazyAllocate(ImmutableGlobals);
  742. assert(K == MemRegion::GlobalInternalSpaceRegionKind);
  743. return LazyAllocate(InternalGlobals);
  744. }
  745. assert(K == MemRegion::StaticGlobalSpaceRegionKind);
  746. StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
  747. if (R)
  748. return R;
  749. R = A.Allocate<StaticGlobalSpaceRegion>();
  750. new (R) StaticGlobalSpaceRegion(*this, CR);
  751. return R;
  752. }
  753. const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
  754. return LazyAllocate(heap);
  755. }
  756. const UnknownSpaceRegion *MemRegionManager::getUnknownRegion() {
  757. return LazyAllocate(unknown);
  758. }
  759. const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
  760. return LazyAllocate(code);
  761. }
  762. //===----------------------------------------------------------------------===//
  763. // Constructing regions.
  764. //===----------------------------------------------------------------------===//
  765. const StringRegion *MemRegionManager::getStringRegion(const StringLiteral *Str){
  766. return getSubRegion<StringRegion>(
  767. Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
  768. }
  769. const ObjCStringRegion *
  770. MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){
  771. return getSubRegion<ObjCStringRegion>(
  772. Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
  773. }
  774. /// Look through a chain of LocationContexts to either find the
  775. /// StackFrameContext that matches a DeclContext, or find a VarRegion
  776. /// for a variable captured by a block.
  777. static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
  778. getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
  779. const DeclContext *DC,
  780. const VarDecl *VD) {
  781. while (LC) {
  782. if (const auto *SFC = dyn_cast<StackFrameContext>(LC)) {
  783. if (cast<DeclContext>(SFC->getDecl()) == DC)
  784. return SFC;
  785. }
  786. if (const auto *BC = dyn_cast<BlockInvocationContext>(LC)) {
  787. const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
  788. // FIXME: This can be made more efficient.
  789. for (BlockDataRegion::referenced_vars_iterator
  790. I = BR->referenced_vars_begin(),
  791. E = BR->referenced_vars_end(); I != E; ++I) {
  792. const TypedValueRegion *OrigR = I.getOriginalRegion();
  793. if (const auto *VR = dyn_cast<VarRegion>(OrigR)) {
  794. if (VR->getDecl() == VD)
  795. return cast<VarRegion>(I.getCapturedRegion());
  796. }
  797. }
  798. }
  799. LC = LC->getParent();
  800. }
  801. return (const StackFrameContext *)nullptr;
  802. }
  803. const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
  804. const LocationContext *LC) {
  805. const auto *PVD = dyn_cast<ParmVarDecl>(D);
  806. if (PVD) {
  807. unsigned Index = PVD->getFunctionScopeIndex();
  808. const StackFrameContext *SFC = LC->getStackFrame();
  809. const Stmt *CallSite = SFC->getCallSite();
  810. if (CallSite) {
  811. const Decl *D = SFC->getDecl();
  812. if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
  813. if (Index < FD->param_size() && FD->parameters()[Index] == PVD)
  814. return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
  815. getStackArgumentsRegion(SFC));
  816. } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
  817. if (Index < BD->param_size() && BD->parameters()[Index] == PVD)
  818. return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
  819. getStackArgumentsRegion(SFC));
  820. } else {
  821. return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
  822. getStackArgumentsRegion(SFC));
  823. }
  824. }
  825. }
  826. D = D->getCanonicalDecl();
  827. const MemRegion *sReg = nullptr;
  828. if (D->hasGlobalStorage() && !D->isStaticLocal()) {
  829. QualType Ty = D->getType();
  830. assert(!Ty.isNull());
  831. if (Ty.isConstQualified()) {
  832. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
  833. } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
  834. sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
  835. } else {
  836. sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
  837. }
  838. // Finally handle static locals.
  839. } else {
  840. // FIXME: Once we implement scope handling, we will need to properly lookup
  841. // 'D' to the proper LocationContext.
  842. const DeclContext *DC = D->getDeclContext();
  843. llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
  844. getStackOrCaptureRegionForDeclContext(LC, DC, D);
  845. if (V.is<const VarRegion*>())
  846. return V.get<const VarRegion*>();
  847. const auto *STC = V.get<const StackFrameContext *>();
  848. if (!STC) {
  849. // FIXME: Assign a more sensible memory space to static locals
  850. // we see from within blocks that we analyze as top-level declarations.
  851. sReg = getUnknownRegion();
  852. } else {
  853. if (D->hasLocalStorage()) {
  854. sReg =
  855. isa<ParmVarDecl, ImplicitParamDecl>(D)
  856. ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
  857. : static_cast<const MemRegion *>(getStackLocalsRegion(STC));
  858. }
  859. else {
  860. assert(D->isStaticLocal());
  861. const Decl *STCD = STC->getDecl();
  862. if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
  863. sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
  864. getFunctionCodeRegion(cast<NamedDecl>(STCD)));
  865. else if (const auto *BD = dyn_cast<BlockDecl>(STCD)) {
  866. // FIXME: The fallback type here is totally bogus -- though it should
  867. // never be queried, it will prevent uniquing with the real
  868. // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
  869. // signature.
  870. QualType T;
  871. if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
  872. T = TSI->getType();
  873. if (T.isNull())
  874. T = getContext().VoidTy;
  875. if (!T->getAs<FunctionType>()) {
  876. FunctionProtoType::ExtProtoInfo Ext;
  877. T = getContext().getFunctionType(T, std::nullopt, Ext);
  878. }
  879. T = getContext().getBlockPointerType(T);
  880. const BlockCodeRegion *BTR =
  881. getBlockCodeRegion(BD, Ctx.getCanonicalType(T),
  882. STC->getAnalysisDeclContext());
  883. sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
  884. BTR);
  885. }
  886. else {
  887. sReg = getGlobalsRegion();
  888. }
  889. }
  890. }
  891. }
  892. return getSubRegion<NonParamVarRegion>(D, sReg);
  893. }
  894. const NonParamVarRegion *
  895. MemRegionManager::getNonParamVarRegion(const VarDecl *D,
  896. const MemRegion *superR) {
  897. D = D->getCanonicalDecl();
  898. return getSubRegion<NonParamVarRegion>(D, superR);
  899. }
  900. const ParamVarRegion *
  901. MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
  902. const LocationContext *LC) {
  903. const StackFrameContext *SFC = LC->getStackFrame();
  904. assert(SFC);
  905. return getSubRegion<ParamVarRegion>(OriginExpr, Index,
  906. getStackArgumentsRegion(SFC));
  907. }
  908. const BlockDataRegion *
  909. MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
  910. const LocationContext *LC,
  911. unsigned blockCount) {
  912. const MemSpaceRegion *sReg = nullptr;
  913. const BlockDecl *BD = BC->getDecl();
  914. if (!BD->hasCaptures()) {
  915. // This handles 'static' blocks.
  916. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
  917. }
  918. else {
  919. bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
  920. // ARC managed blocks can be initialized on stack or directly in heap
  921. // depending on the implementations. So we initialize them with
  922. // UnknownRegion.
  923. if (!IsArcManagedBlock && LC) {
  924. // FIXME: Once we implement scope handling, we want the parent region
  925. // to be the scope.
  926. const StackFrameContext *STC = LC->getStackFrame();
  927. assert(STC);
  928. sReg = getStackLocalsRegion(STC);
  929. } else {
  930. // We allow 'LC' to be NULL for cases where want BlockDataRegions
  931. // without context-sensitivity.
  932. sReg = getUnknownRegion();
  933. }
  934. }
  935. return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
  936. }
  937. const CXXTempObjectRegion *
  938. MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
  939. return getSubRegion<CXXTempObjectRegion>(
  940. Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
  941. }
  942. const CompoundLiteralRegion*
  943. MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
  944. const LocationContext *LC) {
  945. const MemSpaceRegion *sReg = nullptr;
  946. if (CL->isFileScope())
  947. sReg = getGlobalsRegion();
  948. else {
  949. const StackFrameContext *STC = LC->getStackFrame();
  950. assert(STC);
  951. sReg = getStackLocalsRegion(STC);
  952. }
  953. return getSubRegion<CompoundLiteralRegion>(CL, sReg);
  954. }
  955. const ElementRegion*
  956. MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
  957. const SubRegion* superRegion,
  958. ASTContext &Ctx){
  959. QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
  960. llvm::FoldingSetNodeID ID;
  961. ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
  962. void *InsertPos;
  963. MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
  964. auto *R = cast_or_null<ElementRegion>(data);
  965. if (!R) {
  966. R = A.Allocate<ElementRegion>();
  967. new (R) ElementRegion(T, Idx, superRegion);
  968. Regions.InsertNode(R, InsertPos);
  969. }
  970. return R;
  971. }
  972. const FunctionCodeRegion *
  973. MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) {
  974. // To think: should we canonicalize the declaration here?
  975. return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
  976. }
  977. const BlockCodeRegion *
  978. MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy,
  979. AnalysisDeclContext *AC) {
  980. return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion());
  981. }
  982. const SymbolicRegion *
  983. MemRegionManager::getSymbolicRegion(SymbolRef sym,
  984. const MemSpaceRegion *MemSpace) {
  985. if (MemSpace == nullptr)
  986. MemSpace = getUnknownRegion();
  987. return getSubRegion<SymbolicRegion>(sym, MemSpace);
  988. }
  989. const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
  990. return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
  991. }
  992. const FieldRegion*
  993. MemRegionManager::getFieldRegion(const FieldDecl *d,
  994. const SubRegion* superRegion){
  995. return getSubRegion<FieldRegion>(d, superRegion);
  996. }
  997. const ObjCIvarRegion*
  998. MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
  999. const SubRegion* superRegion) {
  1000. return getSubRegion<ObjCIvarRegion>(d, superRegion);
  1001. }
  1002. const CXXTempObjectRegion*
  1003. MemRegionManager::getCXXTempObjectRegion(Expr const *E,
  1004. LocationContext const *LC) {
  1005. const StackFrameContext *SFC = LC->getStackFrame();
  1006. assert(SFC);
  1007. return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
  1008. }
  1009. /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
  1010. /// class of the type of \p Super.
  1011. static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
  1012. const TypedValueRegion *Super,
  1013. bool IsVirtual) {
  1014. BaseClass = BaseClass->getCanonicalDecl();
  1015. const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
  1016. if (!Class)
  1017. return true;
  1018. if (IsVirtual)
  1019. return Class->isVirtuallyDerivedFrom(BaseClass);
  1020. for (const auto &I : Class->bases()) {
  1021. if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
  1022. return true;
  1023. }
  1024. return false;
  1025. }
  1026. const CXXBaseObjectRegion *
  1027. MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
  1028. const SubRegion *Super,
  1029. bool IsVirtual) {
  1030. if (isa<TypedValueRegion>(Super)) {
  1031. assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual));
  1032. (void)&isValidBaseClass;
  1033. if (IsVirtual) {
  1034. // Virtual base regions should not be layered, since the layout rules
  1035. // are different.
  1036. while (const auto *Base = dyn_cast<CXXBaseObjectRegion>(Super))
  1037. Super = cast<SubRegion>(Base->getSuperRegion());
  1038. assert(Super && !isa<MemSpaceRegion>(Super));
  1039. }
  1040. }
  1041. return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
  1042. }
  1043. const CXXDerivedObjectRegion *
  1044. MemRegionManager::getCXXDerivedObjectRegion(const CXXRecordDecl *RD,
  1045. const SubRegion *Super) {
  1046. return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
  1047. }
  1048. const CXXThisRegion*
  1049. MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
  1050. const LocationContext *LC) {
  1051. const auto *PT = thisPointerTy->getAs<PointerType>();
  1052. assert(PT);
  1053. // Inside the body of the operator() of a lambda a this expr might refer to an
  1054. // object in one of the parent location contexts.
  1055. const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl());
  1056. // FIXME: when operator() of lambda is analyzed as a top level function and
  1057. // 'this' refers to a this to the enclosing scope, there is no right region to
  1058. // return.
  1059. while (!LC->inTopFrame() && (!D || D->isStatic() ||
  1060. PT != D->getThisType()->getAs<PointerType>())) {
  1061. LC = LC->getParent();
  1062. D = dyn_cast<CXXMethodDecl>(LC->getDecl());
  1063. }
  1064. const StackFrameContext *STC = LC->getStackFrame();
  1065. assert(STC);
  1066. return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
  1067. }
  1068. const AllocaRegion*
  1069. MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
  1070. const LocationContext *LC) {
  1071. const StackFrameContext *STC = LC->getStackFrame();
  1072. assert(STC);
  1073. return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
  1074. }
  1075. const MemSpaceRegion *MemRegion::getMemorySpace() const {
  1076. const MemRegion *R = this;
  1077. const auto *SR = dyn_cast<SubRegion>(this);
  1078. while (SR) {
  1079. R = SR->getSuperRegion();
  1080. SR = dyn_cast<SubRegion>(R);
  1081. }
  1082. return dyn_cast<MemSpaceRegion>(R);
  1083. }
  1084. bool MemRegion::hasStackStorage() const {
  1085. return isa<StackSpaceRegion>(getMemorySpace());
  1086. }
  1087. bool MemRegion::hasStackNonParametersStorage() const {
  1088. return isa<StackLocalsSpaceRegion>(getMemorySpace());
  1089. }
  1090. bool MemRegion::hasStackParametersStorage() const {
  1091. return isa<StackArgumentsSpaceRegion>(getMemorySpace());
  1092. }
  1093. bool MemRegion::hasGlobalsOrParametersStorage() const {
  1094. return isa<StackArgumentsSpaceRegion, GlobalsSpaceRegion>(getMemorySpace());
  1095. }
  1096. // Strips away all elements and fields.
  1097. // Returns the base region of them.
  1098. const MemRegion *MemRegion::getBaseRegion() const {
  1099. const MemRegion *R = this;
  1100. while (true) {
  1101. switch (R->getKind()) {
  1102. case MemRegion::ElementRegionKind:
  1103. case MemRegion::FieldRegionKind:
  1104. case MemRegion::ObjCIvarRegionKind:
  1105. case MemRegion::CXXBaseObjectRegionKind:
  1106. case MemRegion::CXXDerivedObjectRegionKind:
  1107. R = cast<SubRegion>(R)->getSuperRegion();
  1108. continue;
  1109. default:
  1110. break;
  1111. }
  1112. break;
  1113. }
  1114. return R;
  1115. }
  1116. // Returns the region of the root class of a C++ class hierarchy.
  1117. const MemRegion *MemRegion::getMostDerivedObjectRegion() const {
  1118. const MemRegion *R = this;
  1119. while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
  1120. R = BR->getSuperRegion();
  1121. return R;
  1122. }
  1123. bool MemRegion::isSubRegionOf(const MemRegion *) const {
  1124. return false;
  1125. }
  1126. //===----------------------------------------------------------------------===//
  1127. // View handling.
  1128. //===----------------------------------------------------------------------===//
  1129. const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {
  1130. const MemRegion *R = this;
  1131. while (true) {
  1132. switch (R->getKind()) {
  1133. case ElementRegionKind: {
  1134. const auto *ER = cast<ElementRegion>(R);
  1135. if (!ER->getIndex().isZeroConstant())
  1136. return R;
  1137. R = ER->getSuperRegion();
  1138. break;
  1139. }
  1140. case CXXBaseObjectRegionKind:
  1141. case CXXDerivedObjectRegionKind:
  1142. if (!StripBaseAndDerivedCasts)
  1143. return R;
  1144. R = cast<TypedValueRegion>(R)->getSuperRegion();
  1145. break;
  1146. default:
  1147. return R;
  1148. }
  1149. }
  1150. }
  1151. const SymbolicRegion *MemRegion::getSymbolicBase() const {
  1152. const auto *SubR = dyn_cast<SubRegion>(this);
  1153. while (SubR) {
  1154. if (const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
  1155. return SymR;
  1156. SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
  1157. }
  1158. return nullptr;
  1159. }
  1160. RegionRawOffset ElementRegion::getAsArrayOffset() const {
  1161. int64_t offset = 0;
  1162. const ElementRegion *ER = this;
  1163. const MemRegion *superR = nullptr;
  1164. ASTContext &C = getContext();
  1165. // FIXME: Handle multi-dimensional arrays.
  1166. while (ER) {
  1167. superR = ER->getSuperRegion();
  1168. // FIXME: generalize to symbolic offsets.
  1169. SVal index = ER->getIndex();
  1170. if (auto CI = index.getAs<nonloc::ConcreteInt>()) {
  1171. // Update the offset.
  1172. int64_t i = CI->getValue().getSExtValue();
  1173. if (i != 0) {
  1174. QualType elemType = ER->getElementType();
  1175. // If we are pointing to an incomplete type, go no further.
  1176. if (elemType->isIncompleteType()) {
  1177. superR = ER;
  1178. break;
  1179. }
  1180. int64_t size = C.getTypeSizeInChars(elemType).getQuantity();
  1181. if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
  1182. offset = *NewOffset;
  1183. } else {
  1184. LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: "
  1185. << "offset overflowing, returning unknown\n");
  1186. return nullptr;
  1187. }
  1188. }
  1189. // Go to the next ElementRegion (if any).
  1190. ER = dyn_cast<ElementRegion>(superR);
  1191. continue;
  1192. }
  1193. return nullptr;
  1194. }
  1195. assert(superR && "super region cannot be NULL");
  1196. return RegionRawOffset(superR, CharUnits::fromQuantity(offset));
  1197. }
  1198. /// Returns true if \p Base is an immediate base class of \p Child
  1199. static bool isImmediateBase(const CXXRecordDecl *Child,
  1200. const CXXRecordDecl *Base) {
  1201. assert(Child && "Child must not be null");
  1202. // Note that we do NOT canonicalize the base class here, because
  1203. // ASTRecordLayout doesn't either. If that leads us down the wrong path,
  1204. // so be it; at least we won't crash.
  1205. for (const auto &I : Child->bases()) {
  1206. if (I.getType()->getAsCXXRecordDecl() == Base)
  1207. return true;
  1208. }
  1209. return false;
  1210. }
  1211. static RegionOffset calculateOffset(const MemRegion *R) {
  1212. const MemRegion *SymbolicOffsetBase = nullptr;
  1213. int64_t Offset = 0;
  1214. while (true) {
  1215. switch (R->getKind()) {
  1216. case MemRegion::CodeSpaceRegionKind:
  1217. case MemRegion::StackLocalsSpaceRegionKind:
  1218. case MemRegion::StackArgumentsSpaceRegionKind:
  1219. case MemRegion::HeapSpaceRegionKind:
  1220. case MemRegion::UnknownSpaceRegionKind:
  1221. case MemRegion::StaticGlobalSpaceRegionKind:
  1222. case MemRegion::GlobalInternalSpaceRegionKind:
  1223. case MemRegion::GlobalSystemSpaceRegionKind:
  1224. case MemRegion::GlobalImmutableSpaceRegionKind:
  1225. // Stores can bind directly to a region space to set a default value.
  1226. assert(Offset == 0 && !SymbolicOffsetBase);
  1227. goto Finish;
  1228. case MemRegion::FunctionCodeRegionKind:
  1229. case MemRegion::BlockCodeRegionKind:
  1230. case MemRegion::BlockDataRegionKind:
  1231. // These will never have bindings, but may end up having values requested
  1232. // if the user does some strange casting.
  1233. if (Offset != 0)
  1234. SymbolicOffsetBase = R;
  1235. goto Finish;
  1236. case MemRegion::SymbolicRegionKind:
  1237. case MemRegion::AllocaRegionKind:
  1238. case MemRegion::CompoundLiteralRegionKind:
  1239. case MemRegion::CXXThisRegionKind:
  1240. case MemRegion::StringRegionKind:
  1241. case MemRegion::ObjCStringRegionKind:
  1242. case MemRegion::NonParamVarRegionKind:
  1243. case MemRegion::ParamVarRegionKind:
  1244. case MemRegion::CXXTempObjectRegionKind:
  1245. // Usual base regions.
  1246. goto Finish;
  1247. case MemRegion::ObjCIvarRegionKind:
  1248. // This is a little strange, but it's a compromise between
  1249. // ObjCIvarRegions having unknown compile-time offsets (when using the
  1250. // non-fragile runtime) and yet still being distinct, non-overlapping
  1251. // regions. Thus we treat them as "like" base regions for the purposes
  1252. // of computing offsets.
  1253. goto Finish;
  1254. case MemRegion::CXXBaseObjectRegionKind: {
  1255. const auto *BOR = cast<CXXBaseObjectRegion>(R);
  1256. R = BOR->getSuperRegion();
  1257. QualType Ty;
  1258. bool RootIsSymbolic = false;
  1259. if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
  1260. Ty = TVR->getDesugaredValueType(R->getContext());
  1261. } else if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
  1262. // If our base region is symbolic, we don't know what type it really is.
  1263. // Pretend the type of the symbol is the true dynamic type.
  1264. // (This will at least be self-consistent for the life of the symbol.)
  1265. Ty = SR->getPointeeStaticType();
  1266. RootIsSymbolic = true;
  1267. }
  1268. const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
  1269. if (!Child) {
  1270. // We cannot compute the offset of the base class.
  1271. SymbolicOffsetBase = R;
  1272. } else {
  1273. if (RootIsSymbolic) {
  1274. // Base layers on symbolic regions may not be type-correct.
  1275. // Double-check the inheritance here, and revert to a symbolic offset
  1276. // if it's invalid (e.g. due to a reinterpret_cast).
  1277. if (BOR->isVirtual()) {
  1278. if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
  1279. SymbolicOffsetBase = R;
  1280. } else {
  1281. if (!isImmediateBase(Child, BOR->getDecl()))
  1282. SymbolicOffsetBase = R;
  1283. }
  1284. }
  1285. }
  1286. // Don't bother calculating precise offsets if we already have a
  1287. // symbolic offset somewhere in the chain.
  1288. if (SymbolicOffsetBase)
  1289. continue;
  1290. CharUnits BaseOffset;
  1291. const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
  1292. if (BOR->isVirtual())
  1293. BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
  1294. else
  1295. BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
  1296. // The base offset is in chars, not in bits.
  1297. Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
  1298. break;
  1299. }
  1300. case MemRegion::CXXDerivedObjectRegionKind: {
  1301. // TODO: Store the base type in the CXXDerivedObjectRegion and use it.
  1302. goto Finish;
  1303. }
  1304. case MemRegion::ElementRegionKind: {
  1305. const auto *ER = cast<ElementRegion>(R);
  1306. R = ER->getSuperRegion();
  1307. QualType EleTy = ER->getValueType();
  1308. if (EleTy->isIncompleteType()) {
  1309. // We cannot compute the offset of the base class.
  1310. SymbolicOffsetBase = R;
  1311. continue;
  1312. }
  1313. SVal Index = ER->getIndex();
  1314. if (std::optional<nonloc::ConcreteInt> CI =
  1315. Index.getAs<nonloc::ConcreteInt>()) {
  1316. // Don't bother calculating precise offsets if we already have a
  1317. // symbolic offset somewhere in the chain.
  1318. if (SymbolicOffsetBase)
  1319. continue;
  1320. int64_t i = CI->getValue().getSExtValue();
  1321. // This type size is in bits.
  1322. Offset += i * R->getContext().getTypeSize(EleTy);
  1323. } else {
  1324. // We cannot compute offset for non-concrete index.
  1325. SymbolicOffsetBase = R;
  1326. }
  1327. break;
  1328. }
  1329. case MemRegion::FieldRegionKind: {
  1330. const auto *FR = cast<FieldRegion>(R);
  1331. R = FR->getSuperRegion();
  1332. assert(R);
  1333. const RecordDecl *RD = FR->getDecl()->getParent();
  1334. if (RD->isUnion() || !RD->isCompleteDefinition()) {
  1335. // We cannot compute offset for incomplete type.
  1336. // For unions, we could treat everything as offset 0, but we'd rather
  1337. // treat each field as a symbolic offset so they aren't stored on top
  1338. // of each other, since we depend on things in typed regions actually
  1339. // matching their types.
  1340. SymbolicOffsetBase = R;
  1341. }
  1342. // Don't bother calculating precise offsets if we already have a
  1343. // symbolic offset somewhere in the chain.
  1344. if (SymbolicOffsetBase)
  1345. continue;
  1346. // Get the field number.
  1347. unsigned idx = 0;
  1348. for (RecordDecl::field_iterator FI = RD->field_begin(),
  1349. FE = RD->field_end(); FI != FE; ++FI, ++idx) {
  1350. if (FR->getDecl() == *FI)
  1351. break;
  1352. }
  1353. const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
  1354. // This is offset in bits.
  1355. Offset += Layout.getFieldOffset(idx);
  1356. break;
  1357. }
  1358. }
  1359. }
  1360. Finish:
  1361. if (SymbolicOffsetBase)
  1362. return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
  1363. return RegionOffset(R, Offset);
  1364. }
  1365. RegionOffset MemRegion::getAsOffset() const {
  1366. if (!cachedOffset)
  1367. cachedOffset = calculateOffset(this);
  1368. return *cachedOffset;
  1369. }
  1370. //===----------------------------------------------------------------------===//
  1371. // BlockDataRegion
  1372. //===----------------------------------------------------------------------===//
  1373. std::pair<const VarRegion *, const VarRegion *>
  1374. BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
  1375. MemRegionManager &MemMgr = getMemRegionManager();
  1376. const VarRegion *VR = nullptr;
  1377. const VarRegion *OriginalVR = nullptr;
  1378. if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
  1379. VR = MemMgr.getNonParamVarRegion(VD, this);
  1380. OriginalVR = MemMgr.getVarRegion(VD, LC);
  1381. }
  1382. else {
  1383. if (LC) {
  1384. VR = MemMgr.getVarRegion(VD, LC);
  1385. OriginalVR = VR;
  1386. }
  1387. else {
  1388. VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion());
  1389. OriginalVR = MemMgr.getVarRegion(VD, LC);
  1390. }
  1391. }
  1392. return std::make_pair(VR, OriginalVR);
  1393. }
  1394. void BlockDataRegion::LazyInitializeReferencedVars() {
  1395. if (ReferencedVars)
  1396. return;
  1397. AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
  1398. const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
  1399. auto NumBlockVars =
  1400. std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
  1401. if (NumBlockVars == 0) {
  1402. ReferencedVars = (void*) 0x1;
  1403. return;
  1404. }
  1405. MemRegionManager &MemMgr = getMemRegionManager();
  1406. llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
  1407. BumpVectorContext BC(A);
  1408. using VarVec = BumpVector<const MemRegion *>;
  1409. auto *BV = A.Allocate<VarVec>();
  1410. new (BV) VarVec(BC, NumBlockVars);
  1411. auto *BVOriginal = A.Allocate<VarVec>();
  1412. new (BVOriginal) VarVec(BC, NumBlockVars);
  1413. for (const auto *VD : ReferencedBlockVars) {
  1414. const VarRegion *VR = nullptr;
  1415. const VarRegion *OriginalVR = nullptr;
  1416. std::tie(VR, OriginalVR) = getCaptureRegions(VD);
  1417. assert(VR);
  1418. assert(OriginalVR);
  1419. BV->push_back(VR, BC);
  1420. BVOriginal->push_back(OriginalVR, BC);
  1421. }
  1422. ReferencedVars = BV;
  1423. OriginalVars = BVOriginal;
  1424. }
  1425. BlockDataRegion::referenced_vars_iterator
  1426. BlockDataRegion::referenced_vars_begin() const {
  1427. const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
  1428. auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
  1429. if (Vec == (void*) 0x1)
  1430. return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
  1431. auto *VecOriginal =
  1432. static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
  1433. return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
  1434. VecOriginal->begin());
  1435. }
  1436. BlockDataRegion::referenced_vars_iterator
  1437. BlockDataRegion::referenced_vars_end() const {
  1438. const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
  1439. auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
  1440. if (Vec == (void*) 0x1)
  1441. return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
  1442. auto *VecOriginal =
  1443. static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
  1444. return BlockDataRegion::referenced_vars_iterator(Vec->end(),
  1445. VecOriginal->end());
  1446. }
  1447. const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
  1448. for (referenced_vars_iterator I = referenced_vars_begin(),
  1449. E = referenced_vars_end();
  1450. I != E; ++I) {
  1451. if (I.getCapturedRegion() == R)
  1452. return I.getOriginalRegion();
  1453. }
  1454. return nullptr;
  1455. }
  1456. //===----------------------------------------------------------------------===//
  1457. // RegionAndSymbolInvalidationTraits
  1458. //===----------------------------------------------------------------------===//
  1459. void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
  1460. InvalidationKinds IK) {
  1461. SymTraitsMap[Sym] |= IK;
  1462. }
  1463. void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
  1464. InvalidationKinds IK) {
  1465. assert(MR);
  1466. if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
  1467. setTrait(SR->getSymbol(), IK);
  1468. else
  1469. MRTraitsMap[MR] |= IK;
  1470. }
  1471. bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
  1472. InvalidationKinds IK) const {
  1473. const_symbol_iterator I = SymTraitsMap.find(Sym);
  1474. if (I != SymTraitsMap.end())
  1475. return I->second & IK;
  1476. return false;
  1477. }
  1478. bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
  1479. InvalidationKinds IK) const {
  1480. if (!MR)
  1481. return false;
  1482. if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
  1483. return hasTrait(SR->getSymbol(), IK);
  1484. const_region_iterator I = MRTraitsMap.find(MR);
  1485. if (I != MRTraitsMap.end())
  1486. return I->second & IK;
  1487. return false;
  1488. }