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