MemRegion.cpp 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495
  1. //== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines MemRegion and its subclasses. MemRegion defines a
  11. // partially-typed abstraction of memory useful for path-sensitive dataflow
  12. // analyses.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
  16. #include "clang/AST/Attr.h"
  17. #include "clang/AST/CharUnits.h"
  18. #include "clang/AST/DeclObjC.h"
  19. #include "clang/AST/RecordLayout.h"
  20. #include "clang/Analysis/AnalysisContext.h"
  21. #include "clang/Analysis/Support/BumpVector.h"
  22. #include "clang/Basic/SourceManager.h"
  23. #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. using namespace clang;
  26. using namespace ento;
  27. //===----------------------------------------------------------------------===//
  28. // MemRegion Construction.
  29. //===----------------------------------------------------------------------===//
  30. template<typename RegionTy> struct MemRegionManagerTrait;
  31. template <typename RegionTy, typename A1>
  32. RegionTy* MemRegionManager::getRegion(const A1 a1) {
  33. const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
  34. MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
  35. llvm::FoldingSetNodeID ID;
  36. RegionTy::ProfileRegion(ID, a1, superRegion);
  37. void *InsertPos;
  38. RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
  39. InsertPos));
  40. if (!R) {
  41. R = (RegionTy*) A.Allocate<RegionTy>();
  42. new (R) RegionTy(a1, superRegion);
  43. Regions.InsertNode(R, InsertPos);
  44. }
  45. return R;
  46. }
  47. template <typename RegionTy, typename A1>
  48. RegionTy* MemRegionManager::getSubRegion(const A1 a1,
  49. const MemRegion *superRegion) {
  50. llvm::FoldingSetNodeID ID;
  51. RegionTy::ProfileRegion(ID, a1, superRegion);
  52. void *InsertPos;
  53. RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
  54. InsertPos));
  55. if (!R) {
  56. R = (RegionTy*) A.Allocate<RegionTy>();
  57. new (R) RegionTy(a1, superRegion);
  58. Regions.InsertNode(R, InsertPos);
  59. }
  60. return R;
  61. }
  62. template <typename RegionTy, typename A1, typename A2>
  63. RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
  64. const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
  65. MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
  66. llvm::FoldingSetNodeID ID;
  67. RegionTy::ProfileRegion(ID, a1, a2, superRegion);
  68. void *InsertPos;
  69. RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
  70. InsertPos));
  71. if (!R) {
  72. R = (RegionTy*) A.Allocate<RegionTy>();
  73. new (R) RegionTy(a1, a2, superRegion);
  74. Regions.InsertNode(R, InsertPos);
  75. }
  76. return R;
  77. }
  78. template <typename RegionTy, typename A1, typename A2>
  79. RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
  80. const MemRegion *superRegion) {
  81. llvm::FoldingSetNodeID ID;
  82. RegionTy::ProfileRegion(ID, a1, a2, superRegion);
  83. void *InsertPos;
  84. RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
  85. InsertPos));
  86. if (!R) {
  87. R = (RegionTy*) A.Allocate<RegionTy>();
  88. new (R) RegionTy(a1, a2, superRegion);
  89. Regions.InsertNode(R, InsertPos);
  90. }
  91. return R;
  92. }
  93. template <typename RegionTy, typename A1, typename A2, typename A3>
  94. RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
  95. const MemRegion *superRegion) {
  96. llvm::FoldingSetNodeID ID;
  97. RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
  98. void *InsertPos;
  99. RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
  100. InsertPos));
  101. if (!R) {
  102. R = (RegionTy*) A.Allocate<RegionTy>();
  103. new (R) RegionTy(a1, a2, a3, superRegion);
  104. Regions.InsertNode(R, InsertPos);
  105. }
  106. return R;
  107. }
  108. //===----------------------------------------------------------------------===//
  109. // Object destruction.
  110. //===----------------------------------------------------------------------===//
  111. MemRegion::~MemRegion() {}
  112. MemRegionManager::~MemRegionManager() {
  113. // All regions and their data are BumpPtrAllocated. No need to call
  114. // their destructors.
  115. }
  116. //===----------------------------------------------------------------------===//
  117. // Basic methods.
  118. //===----------------------------------------------------------------------===//
  119. bool SubRegion::isSubRegionOf(const MemRegion* R) const {
  120. const MemRegion* r = getSuperRegion();
  121. while (r != nullptr) {
  122. if (r == R)
  123. return true;
  124. if (const SubRegion* sr = dyn_cast<SubRegion>(r))
  125. r = sr->getSuperRegion();
  126. else
  127. break;
  128. }
  129. return false;
  130. }
  131. MemRegionManager* SubRegion::getMemRegionManager() const {
  132. const SubRegion* r = this;
  133. do {
  134. const MemRegion *superRegion = r->getSuperRegion();
  135. if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
  136. r = sr;
  137. continue;
  138. }
  139. return superRegion->getMemRegionManager();
  140. } while (1);
  141. }
  142. const StackFrameContext *VarRegion::getStackFrame() const {
  143. const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
  144. return SSR ? SSR->getStackFrame() : nullptr;
  145. }
  146. //===----------------------------------------------------------------------===//
  147. // Region extents.
  148. //===----------------------------------------------------------------------===//
  149. DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
  150. ASTContext &Ctx = svalBuilder.getContext();
  151. QualType T = getDesugaredValueType(Ctx);
  152. if (isa<VariableArrayType>(T))
  153. return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
  154. if (T->isIncompleteType())
  155. return UnknownVal();
  156. CharUnits size = Ctx.getTypeSizeInChars(T);
  157. QualType sizeTy = svalBuilder.getArrayIndexType();
  158. return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
  159. }
  160. DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
  161. // Force callers to deal with bitfields explicitly.
  162. if (getDecl()->isBitField())
  163. return UnknownVal();
  164. DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
  165. // A zero-length array at the end of a struct often stands for dynamically-
  166. // allocated extra memory.
  167. if (Extent.isZeroConstant()) {
  168. QualType T = getDesugaredValueType(svalBuilder.getContext());
  169. if (isa<ConstantArrayType>(T))
  170. return UnknownVal();
  171. }
  172. return Extent;
  173. }
  174. DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
  175. return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
  176. }
  177. DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
  178. return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
  179. }
  180. DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
  181. return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
  182. svalBuilder.getArrayIndexType());
  183. }
  184. ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
  185. : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
  186. const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
  187. return cast<ObjCIvarDecl>(D);
  188. }
  189. QualType ObjCIvarRegion::getValueType() const {
  190. return getDecl()->getType();
  191. }
  192. QualType CXXBaseObjectRegion::getValueType() const {
  193. return QualType(getDecl()->getTypeForDecl(), 0);
  194. }
  195. //===----------------------------------------------------------------------===//
  196. // FoldingSet profiling.
  197. //===----------------------------------------------------------------------===//
  198. void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  199. ID.AddInteger((unsigned)getKind());
  200. }
  201. void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  202. ID.AddInteger((unsigned)getKind());
  203. ID.AddPointer(getStackFrame());
  204. }
  205. void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  206. ID.AddInteger((unsigned)getKind());
  207. ID.AddPointer(getCodeRegion());
  208. }
  209. void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  210. const StringLiteral* Str,
  211. const MemRegion* superRegion) {
  212. ID.AddInteger((unsigned) StringRegionKind);
  213. ID.AddPointer(Str);
  214. ID.AddPointer(superRegion);
  215. }
  216. void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  217. const ObjCStringLiteral* Str,
  218. const MemRegion* superRegion) {
  219. ID.AddInteger((unsigned) ObjCStringRegionKind);
  220. ID.AddPointer(Str);
  221. ID.AddPointer(superRegion);
  222. }
  223. void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  224. const Expr *Ex, unsigned cnt,
  225. const MemRegion *superRegion) {
  226. ID.AddInteger((unsigned) AllocaRegionKind);
  227. ID.AddPointer(Ex);
  228. ID.AddInteger(cnt);
  229. ID.AddPointer(superRegion);
  230. }
  231. void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  232. ProfileRegion(ID, Ex, Cnt, superRegion);
  233. }
  234. void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  235. CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
  236. }
  237. void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  238. const CompoundLiteralExpr *CL,
  239. const MemRegion* superRegion) {
  240. ID.AddInteger((unsigned) CompoundLiteralRegionKind);
  241. ID.AddPointer(CL);
  242. ID.AddPointer(superRegion);
  243. }
  244. void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  245. const PointerType *PT,
  246. const MemRegion *sRegion) {
  247. ID.AddInteger((unsigned) CXXThisRegionKind);
  248. ID.AddPointer(PT);
  249. ID.AddPointer(sRegion);
  250. }
  251. void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  252. CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
  253. }
  254. void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  255. const ObjCIvarDecl *ivd,
  256. const MemRegion* superRegion) {
  257. DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
  258. }
  259. void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
  260. const MemRegion* superRegion, Kind k) {
  261. ID.AddInteger((unsigned) k);
  262. ID.AddPointer(D);
  263. ID.AddPointer(superRegion);
  264. }
  265. void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  266. DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
  267. }
  268. void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  269. VarRegion::ProfileRegion(ID, getDecl(), superRegion);
  270. }
  271. void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
  272. const MemRegion *sreg) {
  273. ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
  274. ID.Add(sym);
  275. ID.AddPointer(sreg);
  276. }
  277. void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  278. SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
  279. }
  280. void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  281. QualType ElementType, SVal Idx,
  282. const MemRegion* superRegion) {
  283. ID.AddInteger(MemRegion::ElementRegionKind);
  284. ID.Add(ElementType);
  285. ID.AddPointer(superRegion);
  286. Idx.Profile(ID);
  287. }
  288. void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  289. ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
  290. }
  291. void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  292. const NamedDecl *FD,
  293. const MemRegion*) {
  294. ID.AddInteger(MemRegion::FunctionTextRegionKind);
  295. ID.AddPointer(FD);
  296. }
  297. void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  298. FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
  299. }
  300. void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  301. const BlockDecl *BD, CanQualType,
  302. const AnalysisDeclContext *AC,
  303. const MemRegion*) {
  304. ID.AddInteger(MemRegion::BlockTextRegionKind);
  305. ID.AddPointer(BD);
  306. }
  307. void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  308. BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
  309. }
  310. void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
  311. const BlockTextRegion *BC,
  312. const LocationContext *LC,
  313. unsigned BlkCount,
  314. const MemRegion *sReg) {
  315. ID.AddInteger(MemRegion::BlockDataRegionKind);
  316. ID.AddPointer(BC);
  317. ID.AddPointer(LC);
  318. ID.AddInteger(BlkCount);
  319. ID.AddPointer(sReg);
  320. }
  321. void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
  322. BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
  323. }
  324. void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  325. Expr const *Ex,
  326. const MemRegion *sReg) {
  327. ID.AddPointer(Ex);
  328. ID.AddPointer(sReg);
  329. }
  330. void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  331. ProfileRegion(ID, Ex, getSuperRegion());
  332. }
  333. void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
  334. const CXXRecordDecl *RD,
  335. bool IsVirtual,
  336. const MemRegion *SReg) {
  337. ID.AddPointer(RD);
  338. ID.AddBoolean(IsVirtual);
  339. ID.AddPointer(SReg);
  340. }
  341. void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
  342. ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
  343. }
  344. //===----------------------------------------------------------------------===//
  345. // Region anchors.
  346. //===----------------------------------------------------------------------===//
  347. void GlobalsSpaceRegion::anchor() { }
  348. void HeapSpaceRegion::anchor() { }
  349. void UnknownSpaceRegion::anchor() { }
  350. void StackLocalsSpaceRegion::anchor() { }
  351. void StackArgumentsSpaceRegion::anchor() { }
  352. void TypedRegion::anchor() { }
  353. void TypedValueRegion::anchor() { }
  354. void CodeTextRegion::anchor() { }
  355. void SubRegion::anchor() { }
  356. //===----------------------------------------------------------------------===//
  357. // Region pretty-printing.
  358. //===----------------------------------------------------------------------===//
  359. void MemRegion::dump() const {
  360. dumpToStream(llvm::errs());
  361. }
  362. std::string MemRegion::getString() const {
  363. std::string s;
  364. llvm::raw_string_ostream os(s);
  365. dumpToStream(os);
  366. return os.str();
  367. }
  368. void MemRegion::dumpToStream(raw_ostream &os) const {
  369. os << "<Unknown Region>";
  370. }
  371. void AllocaRegion::dumpToStream(raw_ostream &os) const {
  372. os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
  373. }
  374. void FunctionTextRegion::dumpToStream(raw_ostream &os) const {
  375. os << "code{" << getDecl()->getDeclName().getAsString() << '}';
  376. }
  377. void BlockTextRegion::dumpToStream(raw_ostream &os) const {
  378. os << "block_code{" << (const void*) this << '}';
  379. }
  380. void BlockDataRegion::dumpToStream(raw_ostream &os) const {
  381. os << "block_data{" << BC;
  382. os << "; ";
  383. for (BlockDataRegion::referenced_vars_iterator
  384. I = referenced_vars_begin(),
  385. E = referenced_vars_end(); I != E; ++I)
  386. os << "(" << I.getCapturedRegion() << "," <<
  387. I.getOriginalRegion() << ") ";
  388. os << '}';
  389. }
  390. void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
  391. // FIXME: More elaborate pretty-printing.
  392. os << "{ " << (const void*) CL << " }";
  393. }
  394. void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
  395. os << "temp_object{" << getValueType().getAsString() << ','
  396. << (const void*) Ex << '}';
  397. }
  398. void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
  399. os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
  400. }
  401. void CXXThisRegion::dumpToStream(raw_ostream &os) const {
  402. os << "this";
  403. }
  404. void ElementRegion::dumpToStream(raw_ostream &os) const {
  405. os << "element{" << superRegion << ','
  406. << Index << ',' << getElementType().getAsString() << '}';
  407. }
  408. void FieldRegion::dumpToStream(raw_ostream &os) const {
  409. os << superRegion << "->" << *getDecl();
  410. }
  411. void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
  412. os << "ivar{" << superRegion << ',' << *getDecl() << '}';
  413. }
  414. void StringRegion::dumpToStream(raw_ostream &os) const {
  415. assert(Str != nullptr && "Expecting non-null StringLiteral");
  416. Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
  417. }
  418. void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
  419. assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
  420. Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
  421. }
  422. void SymbolicRegion::dumpToStream(raw_ostream &os) const {
  423. os << "SymRegion{" << sym << '}';
  424. }
  425. void VarRegion::dumpToStream(raw_ostream &os) const {
  426. os << *cast<VarDecl>(D);
  427. }
  428. void RegionRawOffset::dump() const {
  429. dumpToStream(llvm::errs());
  430. }
  431. void RegionRawOffset::dumpToStream(raw_ostream &os) const {
  432. os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
  433. }
  434. void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
  435. os << "StaticGlobalsMemSpace{" << CR << '}';
  436. }
  437. void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
  438. os << "GlobalInternalSpaceRegion";
  439. }
  440. void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
  441. os << "GlobalSystemSpaceRegion";
  442. }
  443. void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
  444. os << "GlobalImmutableSpaceRegion";
  445. }
  446. void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
  447. os << "HeapSpaceRegion";
  448. }
  449. void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
  450. os << "UnknownSpaceRegion";
  451. }
  452. void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
  453. os << "StackArgumentsSpaceRegion";
  454. }
  455. void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
  456. os << "StackLocalsSpaceRegion";
  457. }
  458. bool MemRegion::canPrintPretty() const {
  459. return canPrintPrettyAsExpr();
  460. }
  461. bool MemRegion::canPrintPrettyAsExpr() const {
  462. return false;
  463. }
  464. void MemRegion::printPretty(raw_ostream &os) const {
  465. assert(canPrintPretty() && "This region cannot be printed pretty.");
  466. os << "'";
  467. printPrettyAsExpr(os);
  468. os << "'";
  469. return;
  470. }
  471. void MemRegion::printPrettyAsExpr(raw_ostream &os) const {
  472. llvm_unreachable("This region cannot be printed pretty.");
  473. return;
  474. }
  475. bool VarRegion::canPrintPrettyAsExpr() const {
  476. return true;
  477. }
  478. void VarRegion::printPrettyAsExpr(raw_ostream &os) const {
  479. os << getDecl()->getName();
  480. }
  481. bool ObjCIvarRegion::canPrintPrettyAsExpr() const {
  482. return true;
  483. }
  484. void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
  485. os << getDecl()->getName();
  486. }
  487. bool FieldRegion::canPrintPretty() const {
  488. return true;
  489. }
  490. bool FieldRegion::canPrintPrettyAsExpr() const {
  491. return superRegion->canPrintPrettyAsExpr();
  492. }
  493. void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
  494. assert(canPrintPrettyAsExpr());
  495. superRegion->printPrettyAsExpr(os);
  496. os << "." << getDecl()->getName();
  497. }
  498. void FieldRegion::printPretty(raw_ostream &os) const {
  499. if (canPrintPrettyAsExpr()) {
  500. os << "\'";
  501. printPrettyAsExpr(os);
  502. os << "'";
  503. } else {
  504. os << "field " << "\'" << getDecl()->getName() << "'";
  505. }
  506. return;
  507. }
  508. bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
  509. return superRegion->canPrintPrettyAsExpr();
  510. }
  511. void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
  512. superRegion->printPrettyAsExpr(os);
  513. }
  514. //===----------------------------------------------------------------------===//
  515. // MemRegionManager methods.
  516. //===----------------------------------------------------------------------===//
  517. template <typename REG>
  518. const REG *MemRegionManager::LazyAllocate(REG*& region) {
  519. if (!region) {
  520. region = (REG*) A.Allocate<REG>();
  521. new (region) REG(this);
  522. }
  523. return region;
  524. }
  525. template <typename REG, typename ARG>
  526. const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
  527. if (!region) {
  528. region = (REG*) A.Allocate<REG>();
  529. new (region) REG(this, a);
  530. }
  531. return region;
  532. }
  533. const StackLocalsSpaceRegion*
  534. MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
  535. assert(STC);
  536. StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
  537. if (R)
  538. return R;
  539. R = A.Allocate<StackLocalsSpaceRegion>();
  540. new (R) StackLocalsSpaceRegion(this, STC);
  541. return R;
  542. }
  543. const StackArgumentsSpaceRegion *
  544. MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
  545. assert(STC);
  546. StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
  547. if (R)
  548. return R;
  549. R = A.Allocate<StackArgumentsSpaceRegion>();
  550. new (R) StackArgumentsSpaceRegion(this, STC);
  551. return R;
  552. }
  553. const GlobalsSpaceRegion
  554. *MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
  555. const CodeTextRegion *CR) {
  556. if (!CR) {
  557. if (K == MemRegion::GlobalSystemSpaceRegionKind)
  558. return LazyAllocate(SystemGlobals);
  559. if (K == MemRegion::GlobalImmutableSpaceRegionKind)
  560. return LazyAllocate(ImmutableGlobals);
  561. assert(K == MemRegion::GlobalInternalSpaceRegionKind);
  562. return LazyAllocate(InternalGlobals);
  563. }
  564. assert(K == MemRegion::StaticGlobalSpaceRegionKind);
  565. StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
  566. if (R)
  567. return R;
  568. R = A.Allocate<StaticGlobalSpaceRegion>();
  569. new (R) StaticGlobalSpaceRegion(this, CR);
  570. return R;
  571. }
  572. const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
  573. return LazyAllocate(heap);
  574. }
  575. const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
  576. return LazyAllocate(unknown);
  577. }
  578. const MemSpaceRegion *MemRegionManager::getCodeRegion() {
  579. return LazyAllocate(code);
  580. }
  581. //===----------------------------------------------------------------------===//
  582. // Constructing regions.
  583. //===----------------------------------------------------------------------===//
  584. const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
  585. return getSubRegion<StringRegion>(Str, getGlobalsRegion());
  586. }
  587. const ObjCStringRegion *
  588. MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
  589. return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
  590. }
  591. /// Look through a chain of LocationContexts to either find the
  592. /// StackFrameContext that matches a DeclContext, or find a VarRegion
  593. /// for a variable captured by a block.
  594. static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
  595. getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
  596. const DeclContext *DC,
  597. const VarDecl *VD) {
  598. while (LC) {
  599. if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
  600. if (cast<DeclContext>(SFC->getDecl()) == DC)
  601. return SFC;
  602. }
  603. if (const BlockInvocationContext *BC =
  604. dyn_cast<BlockInvocationContext>(LC)) {
  605. const BlockDataRegion *BR =
  606. static_cast<const BlockDataRegion*>(BC->getContextData());
  607. // FIXME: This can be made more efficient.
  608. for (BlockDataRegion::referenced_vars_iterator
  609. I = BR->referenced_vars_begin(),
  610. E = BR->referenced_vars_end(); I != E; ++I) {
  611. if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
  612. if (VR->getDecl() == VD)
  613. return cast<VarRegion>(I.getCapturedRegion());
  614. }
  615. }
  616. LC = LC->getParent();
  617. }
  618. return (const StackFrameContext *)nullptr;
  619. }
  620. const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
  621. const LocationContext *LC) {
  622. const MemRegion *sReg = nullptr;
  623. if (D->hasGlobalStorage() && !D->isStaticLocal()) {
  624. // First handle the globals defined in system headers.
  625. if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
  626. // Whitelist the system globals which often DO GET modified, assume the
  627. // rest are immutable.
  628. if (D->getName().find("errno") != StringRef::npos)
  629. sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
  630. else
  631. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
  632. // Treat other globals as GlobalInternal unless they are constants.
  633. } else {
  634. QualType GQT = D->getType();
  635. const Type *GT = GQT.getTypePtrOrNull();
  636. // TODO: We could walk the complex types here and see if everything is
  637. // constified.
  638. if (GT && GQT.isConstQualified() && GT->isArithmeticType())
  639. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
  640. else
  641. sReg = getGlobalsRegion();
  642. }
  643. // Finally handle static locals.
  644. } else {
  645. // FIXME: Once we implement scope handling, we will need to properly lookup
  646. // 'D' to the proper LocationContext.
  647. const DeclContext *DC = D->getDeclContext();
  648. llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
  649. getStackOrCaptureRegionForDeclContext(LC, DC, D);
  650. if (V.is<const VarRegion*>())
  651. return V.get<const VarRegion*>();
  652. const StackFrameContext *STC = V.get<const StackFrameContext*>();
  653. if (!STC)
  654. sReg = getUnknownRegion();
  655. else {
  656. if (D->hasLocalStorage()) {
  657. sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
  658. ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
  659. : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
  660. }
  661. else {
  662. assert(D->isStaticLocal());
  663. const Decl *STCD = STC->getDecl();
  664. if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
  665. sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
  666. getFunctionTextRegion(cast<NamedDecl>(STCD)));
  667. else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
  668. // FIXME: The fallback type here is totally bogus -- though it should
  669. // never be queried, it will prevent uniquing with the real
  670. // BlockTextRegion. Ideally we'd fix the AST so that we always had a
  671. // signature.
  672. QualType T;
  673. if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
  674. T = TSI->getType();
  675. if (T.isNull())
  676. T = getContext().VoidTy;
  677. if (!T->getAs<FunctionType>())
  678. T = getContext().getFunctionNoProtoType(T);
  679. T = getContext().getBlockPointerType(T);
  680. const BlockTextRegion *BTR =
  681. getBlockTextRegion(BD, C.getCanonicalType(T),
  682. STC->getAnalysisDeclContext());
  683. sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
  684. BTR);
  685. }
  686. else {
  687. sReg = getGlobalsRegion();
  688. }
  689. }
  690. }
  691. }
  692. return getSubRegion<VarRegion>(D, sReg);
  693. }
  694. const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
  695. const MemRegion *superR) {
  696. return getSubRegion<VarRegion>(D, superR);
  697. }
  698. const BlockDataRegion *
  699. MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
  700. const LocationContext *LC,
  701. unsigned blockCount) {
  702. const MemRegion *sReg = nullptr;
  703. const BlockDecl *BD = BC->getDecl();
  704. if (!BD->hasCaptures()) {
  705. // This handles 'static' blocks.
  706. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
  707. }
  708. else {
  709. if (LC) {
  710. // FIXME: Once we implement scope handling, we want the parent region
  711. // to be the scope.
  712. const StackFrameContext *STC = LC->getCurrentStackFrame();
  713. assert(STC);
  714. sReg = getStackLocalsRegion(STC);
  715. }
  716. else {
  717. // We allow 'LC' to be NULL for cases where want BlockDataRegions
  718. // without context-sensitivity.
  719. sReg = getUnknownRegion();
  720. }
  721. }
  722. return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
  723. }
  724. const CXXTempObjectRegion *
  725. MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
  726. return getSubRegion<CXXTempObjectRegion>(
  727. Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
  728. }
  729. const CompoundLiteralRegion*
  730. MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
  731. const LocationContext *LC) {
  732. const MemRegion *sReg = nullptr;
  733. if (CL->isFileScope())
  734. sReg = getGlobalsRegion();
  735. else {
  736. const StackFrameContext *STC = LC->getCurrentStackFrame();
  737. assert(STC);
  738. sReg = getStackLocalsRegion(STC);
  739. }
  740. return getSubRegion<CompoundLiteralRegion>(CL, sReg);
  741. }
  742. const ElementRegion*
  743. MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
  744. const MemRegion* superRegion,
  745. ASTContext &Ctx){
  746. QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
  747. llvm::FoldingSetNodeID ID;
  748. ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
  749. void *InsertPos;
  750. MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
  751. ElementRegion* R = cast_or_null<ElementRegion>(data);
  752. if (!R) {
  753. R = (ElementRegion*) A.Allocate<ElementRegion>();
  754. new (R) ElementRegion(T, Idx, superRegion);
  755. Regions.InsertNode(R, InsertPos);
  756. }
  757. return R;
  758. }
  759. const FunctionTextRegion *
  760. MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
  761. return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
  762. }
  763. const BlockTextRegion *
  764. MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
  765. AnalysisDeclContext *AC) {
  766. return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
  767. }
  768. /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
  769. const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
  770. return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
  771. }
  772. const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
  773. return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
  774. }
  775. const FieldRegion*
  776. MemRegionManager::getFieldRegion(const FieldDecl *d,
  777. const MemRegion* superRegion){
  778. return getSubRegion<FieldRegion>(d, superRegion);
  779. }
  780. const ObjCIvarRegion*
  781. MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
  782. const MemRegion* superRegion) {
  783. return getSubRegion<ObjCIvarRegion>(d, superRegion);
  784. }
  785. const CXXTempObjectRegion*
  786. MemRegionManager::getCXXTempObjectRegion(Expr const *E,
  787. LocationContext const *LC) {
  788. const StackFrameContext *SFC = LC->getCurrentStackFrame();
  789. assert(SFC);
  790. return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
  791. }
  792. /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
  793. /// class of the type of \p Super.
  794. static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
  795. const TypedValueRegion *Super,
  796. bool IsVirtual) {
  797. BaseClass = BaseClass->getCanonicalDecl();
  798. const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
  799. if (!Class)
  800. return true;
  801. if (IsVirtual)
  802. return Class->isVirtuallyDerivedFrom(BaseClass);
  803. for (const auto &I : Class->bases()) {
  804. if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
  805. return true;
  806. }
  807. return false;
  808. }
  809. const CXXBaseObjectRegion *
  810. MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
  811. const MemRegion *Super,
  812. bool IsVirtual) {
  813. if (isa<TypedValueRegion>(Super)) {
  814. assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
  815. (void)&isValidBaseClass;
  816. if (IsVirtual) {
  817. // Virtual base regions should not be layered, since the layout rules
  818. // are different.
  819. while (const CXXBaseObjectRegion *Base =
  820. dyn_cast<CXXBaseObjectRegion>(Super)) {
  821. Super = Base->getSuperRegion();
  822. }
  823. assert(Super && !isa<MemSpaceRegion>(Super));
  824. }
  825. }
  826. return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
  827. }
  828. const CXXThisRegion*
  829. MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
  830. const LocationContext *LC) {
  831. const StackFrameContext *STC = LC->getCurrentStackFrame();
  832. assert(STC);
  833. const PointerType *PT = thisPointerTy->getAs<PointerType>();
  834. assert(PT);
  835. return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
  836. }
  837. const AllocaRegion*
  838. MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
  839. const LocationContext *LC) {
  840. const StackFrameContext *STC = LC->getCurrentStackFrame();
  841. assert(STC);
  842. return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
  843. }
  844. const MemSpaceRegion *MemRegion::getMemorySpace() const {
  845. const MemRegion *R = this;
  846. const SubRegion* SR = dyn_cast<SubRegion>(this);
  847. while (SR) {
  848. R = SR->getSuperRegion();
  849. SR = dyn_cast<SubRegion>(R);
  850. }
  851. return dyn_cast<MemSpaceRegion>(R);
  852. }
  853. bool MemRegion::hasStackStorage() const {
  854. return isa<StackSpaceRegion>(getMemorySpace());
  855. }
  856. bool MemRegion::hasStackNonParametersStorage() const {
  857. return isa<StackLocalsSpaceRegion>(getMemorySpace());
  858. }
  859. bool MemRegion::hasStackParametersStorage() const {
  860. return isa<StackArgumentsSpaceRegion>(getMemorySpace());
  861. }
  862. bool MemRegion::hasGlobalsOrParametersStorage() const {
  863. const MemSpaceRegion *MS = getMemorySpace();
  864. return isa<StackArgumentsSpaceRegion>(MS) ||
  865. isa<GlobalsSpaceRegion>(MS);
  866. }
  867. // getBaseRegion strips away all elements and fields, and get the base region
  868. // of them.
  869. const MemRegion *MemRegion::getBaseRegion() const {
  870. const MemRegion *R = this;
  871. while (true) {
  872. switch (R->getKind()) {
  873. case MemRegion::ElementRegionKind:
  874. case MemRegion::FieldRegionKind:
  875. case MemRegion::ObjCIvarRegionKind:
  876. case MemRegion::CXXBaseObjectRegionKind:
  877. R = cast<SubRegion>(R)->getSuperRegion();
  878. continue;
  879. default:
  880. break;
  881. }
  882. break;
  883. }
  884. return R;
  885. }
  886. bool MemRegion::isSubRegionOf(const MemRegion *R) const {
  887. return false;
  888. }
  889. //===----------------------------------------------------------------------===//
  890. // View handling.
  891. //===----------------------------------------------------------------------===//
  892. const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
  893. const MemRegion *R = this;
  894. while (true) {
  895. switch (R->getKind()) {
  896. case ElementRegionKind: {
  897. const ElementRegion *ER = cast<ElementRegion>(R);
  898. if (!ER->getIndex().isZeroConstant())
  899. return R;
  900. R = ER->getSuperRegion();
  901. break;
  902. }
  903. case CXXBaseObjectRegionKind:
  904. if (!StripBaseCasts)
  905. return R;
  906. R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
  907. break;
  908. default:
  909. return R;
  910. }
  911. }
  912. }
  913. const SymbolicRegion *MemRegion::getSymbolicBase() const {
  914. const SubRegion *SubR = dyn_cast<SubRegion>(this);
  915. while (SubR) {
  916. if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
  917. return SymR;
  918. SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
  919. }
  920. return nullptr;
  921. }
  922. RegionRawOffset ElementRegion::getAsArrayOffset() const {
  923. CharUnits offset = CharUnits::Zero();
  924. const ElementRegion *ER = this;
  925. const MemRegion *superR = nullptr;
  926. ASTContext &C = getContext();
  927. // FIXME: Handle multi-dimensional arrays.
  928. while (ER) {
  929. superR = ER->getSuperRegion();
  930. // FIXME: generalize to symbolic offsets.
  931. SVal index = ER->getIndex();
  932. if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) {
  933. // Update the offset.
  934. int64_t i = CI->getValue().getSExtValue();
  935. if (i != 0) {
  936. QualType elemType = ER->getElementType();
  937. // If we are pointing to an incomplete type, go no further.
  938. if (elemType->isIncompleteType()) {
  939. superR = ER;
  940. break;
  941. }
  942. CharUnits size = C.getTypeSizeInChars(elemType);
  943. offset += (i * size);
  944. }
  945. // Go to the next ElementRegion (if any).
  946. ER = dyn_cast<ElementRegion>(superR);
  947. continue;
  948. }
  949. return nullptr;
  950. }
  951. assert(superR && "super region cannot be NULL");
  952. return RegionRawOffset(superR, offset);
  953. }
  954. /// Returns true if \p Base is an immediate base class of \p Child
  955. static bool isImmediateBase(const CXXRecordDecl *Child,
  956. const CXXRecordDecl *Base) {
  957. // Note that we do NOT canonicalize the base class here, because
  958. // ASTRecordLayout doesn't either. If that leads us down the wrong path,
  959. // so be it; at least we won't crash.
  960. for (const auto &I : Child->bases()) {
  961. if (I.getType()->getAsCXXRecordDecl() == Base)
  962. return true;
  963. }
  964. return false;
  965. }
  966. RegionOffset MemRegion::getAsOffset() const {
  967. const MemRegion *R = this;
  968. const MemRegion *SymbolicOffsetBase = nullptr;
  969. int64_t Offset = 0;
  970. while (1) {
  971. switch (R->getKind()) {
  972. case GenericMemSpaceRegionKind:
  973. case StackLocalsSpaceRegionKind:
  974. case StackArgumentsSpaceRegionKind:
  975. case HeapSpaceRegionKind:
  976. case UnknownSpaceRegionKind:
  977. case StaticGlobalSpaceRegionKind:
  978. case GlobalInternalSpaceRegionKind:
  979. case GlobalSystemSpaceRegionKind:
  980. case GlobalImmutableSpaceRegionKind:
  981. // Stores can bind directly to a region space to set a default value.
  982. assert(Offset == 0 && !SymbolicOffsetBase);
  983. goto Finish;
  984. case FunctionTextRegionKind:
  985. case BlockTextRegionKind:
  986. case BlockDataRegionKind:
  987. // These will never have bindings, but may end up having values requested
  988. // if the user does some strange casting.
  989. if (Offset != 0)
  990. SymbolicOffsetBase = R;
  991. goto Finish;
  992. case SymbolicRegionKind:
  993. case AllocaRegionKind:
  994. case CompoundLiteralRegionKind:
  995. case CXXThisRegionKind:
  996. case StringRegionKind:
  997. case ObjCStringRegionKind:
  998. case VarRegionKind:
  999. case CXXTempObjectRegionKind:
  1000. // Usual base regions.
  1001. goto Finish;
  1002. case ObjCIvarRegionKind:
  1003. // This is a little strange, but it's a compromise between
  1004. // ObjCIvarRegions having unknown compile-time offsets (when using the
  1005. // non-fragile runtime) and yet still being distinct, non-overlapping
  1006. // regions. Thus we treat them as "like" base regions for the purposes
  1007. // of computing offsets.
  1008. goto Finish;
  1009. case CXXBaseObjectRegionKind: {
  1010. const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
  1011. R = BOR->getSuperRegion();
  1012. QualType Ty;
  1013. bool RootIsSymbolic = false;
  1014. if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
  1015. Ty = TVR->getDesugaredValueType(getContext());
  1016. } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
  1017. // If our base region is symbolic, we don't know what type it really is.
  1018. // Pretend the type of the symbol is the true dynamic type.
  1019. // (This will at least be self-consistent for the life of the symbol.)
  1020. Ty = SR->getSymbol()->getType()->getPointeeType();
  1021. RootIsSymbolic = true;
  1022. }
  1023. const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
  1024. if (!Child) {
  1025. // We cannot compute the offset of the base class.
  1026. SymbolicOffsetBase = R;
  1027. }
  1028. if (RootIsSymbolic) {
  1029. // Base layers on symbolic regions may not be type-correct.
  1030. // Double-check the inheritance here, and revert to a symbolic offset
  1031. // if it's invalid (e.g. due to a reinterpret_cast).
  1032. if (BOR->isVirtual()) {
  1033. if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
  1034. SymbolicOffsetBase = R;
  1035. } else {
  1036. if (!isImmediateBase(Child, BOR->getDecl()))
  1037. SymbolicOffsetBase = R;
  1038. }
  1039. }
  1040. // Don't bother calculating precise offsets if we already have a
  1041. // symbolic offset somewhere in the chain.
  1042. if (SymbolicOffsetBase)
  1043. continue;
  1044. CharUnits BaseOffset;
  1045. const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
  1046. if (BOR->isVirtual())
  1047. BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
  1048. else
  1049. BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
  1050. // The base offset is in chars, not in bits.
  1051. Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
  1052. break;
  1053. }
  1054. case ElementRegionKind: {
  1055. const ElementRegion *ER = cast<ElementRegion>(R);
  1056. R = ER->getSuperRegion();
  1057. QualType EleTy = ER->getValueType();
  1058. if (EleTy->isIncompleteType()) {
  1059. // We cannot compute the offset of the base class.
  1060. SymbolicOffsetBase = R;
  1061. continue;
  1062. }
  1063. SVal Index = ER->getIndex();
  1064. if (Optional<nonloc::ConcreteInt> CI =
  1065. Index.getAs<nonloc::ConcreteInt>()) {
  1066. // Don't bother calculating precise offsets if we already have a
  1067. // symbolic offset somewhere in the chain.
  1068. if (SymbolicOffsetBase)
  1069. continue;
  1070. int64_t i = CI->getValue().getSExtValue();
  1071. // This type size is in bits.
  1072. Offset += i * getContext().getTypeSize(EleTy);
  1073. } else {
  1074. // We cannot compute offset for non-concrete index.
  1075. SymbolicOffsetBase = R;
  1076. }
  1077. break;
  1078. }
  1079. case FieldRegionKind: {
  1080. const FieldRegion *FR = cast<FieldRegion>(R);
  1081. R = FR->getSuperRegion();
  1082. const RecordDecl *RD = FR->getDecl()->getParent();
  1083. if (RD->isUnion() || !RD->isCompleteDefinition()) {
  1084. // We cannot compute offset for incomplete type.
  1085. // For unions, we could treat everything as offset 0, but we'd rather
  1086. // treat each field as a symbolic offset so they aren't stored on top
  1087. // of each other, since we depend on things in typed regions actually
  1088. // matching their types.
  1089. SymbolicOffsetBase = R;
  1090. }
  1091. // Don't bother calculating precise offsets if we already have a
  1092. // symbolic offset somewhere in the chain.
  1093. if (SymbolicOffsetBase)
  1094. continue;
  1095. // Get the field number.
  1096. unsigned idx = 0;
  1097. for (RecordDecl::field_iterator FI = RD->field_begin(),
  1098. FE = RD->field_end(); FI != FE; ++FI, ++idx)
  1099. if (FR->getDecl() == *FI)
  1100. break;
  1101. const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
  1102. // This is offset in bits.
  1103. Offset += Layout.getFieldOffset(idx);
  1104. break;
  1105. }
  1106. }
  1107. }
  1108. Finish:
  1109. if (SymbolicOffsetBase)
  1110. return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
  1111. return RegionOffset(R, Offset);
  1112. }
  1113. //===----------------------------------------------------------------------===//
  1114. // BlockDataRegion
  1115. //===----------------------------------------------------------------------===//
  1116. std::pair<const VarRegion *, const VarRegion *>
  1117. BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
  1118. MemRegionManager &MemMgr = *getMemRegionManager();
  1119. const VarRegion *VR = nullptr;
  1120. const VarRegion *OriginalVR = nullptr;
  1121. if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
  1122. VR = MemMgr.getVarRegion(VD, this);
  1123. OriginalVR = MemMgr.getVarRegion(VD, LC);
  1124. }
  1125. else {
  1126. if (LC) {
  1127. VR = MemMgr.getVarRegion(VD, LC);
  1128. OriginalVR = VR;
  1129. }
  1130. else {
  1131. VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
  1132. OriginalVR = MemMgr.getVarRegion(VD, LC);
  1133. }
  1134. }
  1135. return std::make_pair(VR, OriginalVR);
  1136. }
  1137. void BlockDataRegion::LazyInitializeReferencedVars() {
  1138. if (ReferencedVars)
  1139. return;
  1140. AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
  1141. const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
  1142. auto NumBlockVars =
  1143. std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
  1144. if (NumBlockVars == 0) {
  1145. ReferencedVars = (void*) 0x1;
  1146. return;
  1147. }
  1148. MemRegionManager &MemMgr = *getMemRegionManager();
  1149. llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
  1150. BumpVectorContext BC(A);
  1151. typedef BumpVector<const MemRegion*> VarVec;
  1152. VarVec *BV = (VarVec*) A.Allocate<VarVec>();
  1153. new (BV) VarVec(BC, NumBlockVars);
  1154. VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
  1155. new (BVOriginal) VarVec(BC, NumBlockVars);
  1156. for (const VarDecl *VD : ReferencedBlockVars) {
  1157. const VarRegion *VR = nullptr;
  1158. const VarRegion *OriginalVR = nullptr;
  1159. std::tie(VR, OriginalVR) = getCaptureRegions(VD);
  1160. assert(VR);
  1161. assert(OriginalVR);
  1162. BV->push_back(VR, BC);
  1163. BVOriginal->push_back(OriginalVR, BC);
  1164. }
  1165. ReferencedVars = BV;
  1166. OriginalVars = BVOriginal;
  1167. }
  1168. BlockDataRegion::referenced_vars_iterator
  1169. BlockDataRegion::referenced_vars_begin() const {
  1170. const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
  1171. BumpVector<const MemRegion*> *Vec =
  1172. static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
  1173. if (Vec == (void*) 0x1)
  1174. return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
  1175. BumpVector<const MemRegion*> *VecOriginal =
  1176. static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
  1177. return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
  1178. VecOriginal->begin());
  1179. }
  1180. BlockDataRegion::referenced_vars_iterator
  1181. BlockDataRegion::referenced_vars_end() const {
  1182. const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
  1183. BumpVector<const MemRegion*> *Vec =
  1184. static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
  1185. if (Vec == (void*) 0x1)
  1186. return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
  1187. BumpVector<const MemRegion*> *VecOriginal =
  1188. static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
  1189. return BlockDataRegion::referenced_vars_iterator(Vec->end(),
  1190. VecOriginal->end());
  1191. }
  1192. const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
  1193. for (referenced_vars_iterator I = referenced_vars_begin(),
  1194. E = referenced_vars_end();
  1195. I != E; ++I) {
  1196. if (I.getCapturedRegion() == R)
  1197. return I.getOriginalRegion();
  1198. }
  1199. return nullptr;
  1200. }
  1201. //===----------------------------------------------------------------------===//
  1202. // RegionAndSymbolInvalidationTraits
  1203. //===----------------------------------------------------------------------===//
  1204. void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
  1205. InvalidationKinds IK) {
  1206. SymTraitsMap[Sym] |= IK;
  1207. }
  1208. void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
  1209. InvalidationKinds IK) {
  1210. assert(MR);
  1211. if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
  1212. setTrait(SR->getSymbol(), IK);
  1213. else
  1214. MRTraitsMap[MR] |= IK;
  1215. }
  1216. bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
  1217. InvalidationKinds IK) {
  1218. const_symbol_iterator I = SymTraitsMap.find(Sym);
  1219. if (I != SymTraitsMap.end())
  1220. return I->second & IK;
  1221. return false;
  1222. }
  1223. bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
  1224. InvalidationKinds IK) {
  1225. if (!MR)
  1226. return false;
  1227. if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
  1228. return hasTrait(SR->getSymbol(), IK);
  1229. const_region_iterator I = MRTraitsMap.find(MR);
  1230. if (I != MRTraitsMap.end())
  1231. return I->second & IK;
  1232. return false;
  1233. }