MemRegion.cpp 49 KB

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