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