1 //== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines MemRegion and its subclasses. MemRegion defines a
11 // partially-typed abstraction of memory useful for path-sensitive dataflow
14 //===----------------------------------------------------------------------===//
16 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/CharUnits.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/RecordLayout.h"
21 #include "clang/Analysis/AnalysisContext.h"
22 #include "clang/Analysis/Support/BumpVector.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
25 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
30 //===----------------------------------------------------------------------===//
31 // MemRegion Construction.
32 //===----------------------------------------------------------------------===//
34 template <typename RegionTy, typename A1>
35 RegionTy* MemRegionManager::getSubRegion(const A1 a1,
36 const MemRegion *superRegion) {
37 llvm::FoldingSetNodeID ID;
38 RegionTy::ProfileRegion(ID, a1, superRegion);
40 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
44 R = A.Allocate<RegionTy>();
45 new (R) RegionTy(a1, superRegion);
46 Regions.InsertNode(R, InsertPos);
52 template <typename RegionTy, typename A1, typename A2>
53 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
54 const MemRegion *superRegion) {
55 llvm::FoldingSetNodeID ID;
56 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
58 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
62 R = A.Allocate<RegionTy>();
63 new (R) RegionTy(a1, a2, superRegion);
64 Regions.InsertNode(R, InsertPos);
70 template <typename RegionTy, typename A1, typename A2, typename A3>
71 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
72 const MemRegion *superRegion) {
73 llvm::FoldingSetNodeID ID;
74 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
76 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
80 R = A.Allocate<RegionTy>();
81 new (R) RegionTy(a1, a2, a3, superRegion);
82 Regions.InsertNode(R, InsertPos);
88 //===----------------------------------------------------------------------===//
89 // Object destruction.
90 //===----------------------------------------------------------------------===//
92 MemRegion::~MemRegion() {}
94 MemRegionManager::~MemRegionManager() {
95 // All regions and their data are BumpPtrAllocated. No need to call
99 //===----------------------------------------------------------------------===//
101 //===----------------------------------------------------------------------===//
103 bool SubRegion::isSubRegionOf(const MemRegion* R) const {
104 const MemRegion* r = getSuperRegion();
105 while (r != nullptr) {
108 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
109 r = sr->getSuperRegion();
116 MemRegionManager* SubRegion::getMemRegionManager() const {
117 const SubRegion* r = this;
119 const MemRegion *superRegion = r->getSuperRegion();
120 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
124 return superRegion->getMemRegionManager();
128 const StackFrameContext *VarRegion::getStackFrame() const {
129 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
130 return SSR ? SSR->getStackFrame() : nullptr;
133 //===----------------------------------------------------------------------===//
135 //===----------------------------------------------------------------------===//
137 DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
138 ASTContext &Ctx = svalBuilder.getContext();
139 QualType T = getDesugaredValueType(Ctx);
141 if (isa<VariableArrayType>(T))
142 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
143 if (T->isIncompleteType())
146 CharUnits size = Ctx.getTypeSizeInChars(T);
147 QualType sizeTy = svalBuilder.getArrayIndexType();
148 return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
151 DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
152 // Force callers to deal with bitfields explicitly.
153 if (getDecl()->isBitField())
156 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
158 // A zero-length array at the end of a struct often stands for dynamically-
159 // allocated extra memory.
160 if (Extent.isZeroConstant()) {
161 QualType T = getDesugaredValueType(svalBuilder.getContext());
163 if (isa<ConstantArrayType>(T))
170 DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
171 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
174 DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
175 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
178 DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
179 return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
180 svalBuilder.getArrayIndexType());
183 ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
184 : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
186 const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
187 return cast<ObjCIvarDecl>(D);
190 QualType ObjCIvarRegion::getValueType() const {
191 return getDecl()->getType();
194 QualType CXXBaseObjectRegion::getValueType() const {
195 return QualType(getDecl()->getTypeForDecl(), 0);
198 //===----------------------------------------------------------------------===//
199 // FoldingSet profiling.
200 //===----------------------------------------------------------------------===//
202 void MemSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
203 ID.AddInteger(static_cast<unsigned>(getKind()));
206 void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
207 ID.AddInteger(static_cast<unsigned>(getKind()));
208 ID.AddPointer(getStackFrame());
211 void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
212 ID.AddInteger(static_cast<unsigned>(getKind()));
213 ID.AddPointer(getCodeRegion());
216 void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
217 const StringLiteral* Str,
218 const MemRegion* superRegion) {
219 ID.AddInteger(static_cast<unsigned>(StringRegionKind));
221 ID.AddPointer(superRegion);
224 void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
225 const ObjCStringLiteral* Str,
226 const MemRegion* superRegion) {
227 ID.AddInteger(static_cast<unsigned>(ObjCStringRegionKind));
229 ID.AddPointer(superRegion);
232 void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
233 const Expr *Ex, unsigned cnt,
234 const MemRegion *superRegion) {
235 ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
238 ID.AddPointer(superRegion);
241 void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
242 ProfileRegion(ID, Ex, Cnt, superRegion);
245 void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
246 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
249 void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
250 const CompoundLiteralExpr *CL,
251 const MemRegion* superRegion) {
252 ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
254 ID.AddPointer(superRegion);
257 void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
258 const PointerType *PT,
259 const MemRegion *sRegion) {
260 ID.AddInteger(static_cast<unsigned>(CXXThisRegionKind));
262 ID.AddPointer(sRegion);
265 void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
266 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
269 void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
270 const ObjCIvarDecl *ivd,
271 const MemRegion* superRegion) {
272 DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
275 void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
276 const MemRegion* superRegion, Kind k) {
277 ID.AddInteger(static_cast<unsigned>(k));
279 ID.AddPointer(superRegion);
282 void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
283 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
286 void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
287 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
290 void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
291 const MemRegion *sreg) {
292 ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
297 void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
298 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
301 void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
302 QualType ElementType, SVal Idx,
303 const MemRegion* superRegion) {
304 ID.AddInteger(MemRegion::ElementRegionKind);
306 ID.AddPointer(superRegion);
310 void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
311 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
314 void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
317 ID.AddInteger(MemRegion::FunctionCodeRegionKind);
321 void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
322 FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
325 void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
326 const BlockDecl *BD, CanQualType,
327 const AnalysisDeclContext *AC,
329 ID.AddInteger(MemRegion::BlockCodeRegionKind);
333 void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
334 BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
337 void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
338 const BlockCodeRegion *BC,
339 const LocationContext *LC,
341 const MemRegion *sReg) {
342 ID.AddInteger(MemRegion::BlockDataRegionKind);
345 ID.AddInteger(BlkCount);
349 void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
350 BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
353 void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
355 const MemRegion *sReg) {
360 void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
361 ProfileRegion(ID, Ex, getSuperRegion());
364 void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
365 const CXXRecordDecl *RD,
367 const MemRegion *SReg) {
369 ID.AddBoolean(IsVirtual);
373 void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
374 ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
377 //===----------------------------------------------------------------------===//
379 //===----------------------------------------------------------------------===//
381 void GlobalsSpaceRegion::anchor() { }
382 void HeapSpaceRegion::anchor() { }
383 void UnknownSpaceRegion::anchor() { }
384 void StackLocalsSpaceRegion::anchor() { }
385 void StackArgumentsSpaceRegion::anchor() { }
386 void TypedRegion::anchor() { }
387 void TypedValueRegion::anchor() { }
388 void CodeTextRegion::anchor() { }
389 void SubRegion::anchor() { }
391 //===----------------------------------------------------------------------===//
392 // Region pretty-printing.
393 //===----------------------------------------------------------------------===//
395 LLVM_DUMP_METHOD void MemRegion::dump() const {
396 dumpToStream(llvm::errs());
399 std::string MemRegion::getString() const {
401 llvm::raw_string_ostream os(s);
406 void MemRegion::dumpToStream(raw_ostream &os) const {
407 os << "<Unknown Region>";
410 void AllocaRegion::dumpToStream(raw_ostream &os) const {
411 os << "alloca{" << static_cast<const void*>(Ex) << ',' << Cnt << '}';
414 void FunctionCodeRegion::dumpToStream(raw_ostream &os) const {
415 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
418 void BlockCodeRegion::dumpToStream(raw_ostream &os) const {
419 os << "block_code{" << static_cast<const void*>(this) << '}';
422 void BlockDataRegion::dumpToStream(raw_ostream &os) const {
423 os << "block_data{" << BC;
425 for (BlockDataRegion::referenced_vars_iterator
426 I = referenced_vars_begin(),
427 E = referenced_vars_end(); I != E; ++I)
428 os << "(" << I.getCapturedRegion() << "," <<
429 I.getOriginalRegion() << ") ";
433 void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
434 // FIXME: More elaborate pretty-printing.
435 os << "{ " << static_cast<const void*>(CL) << " }";
438 void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
439 os << "temp_object{" << getValueType().getAsString() << ','
440 << static_cast<const void*>(Ex) << '}';
443 void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
444 os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
447 void CXXThisRegion::dumpToStream(raw_ostream &os) const {
451 void ElementRegion::dumpToStream(raw_ostream &os) const {
452 os << "element{" << superRegion << ','
453 << Index << ',' << getElementType().getAsString() << '}';
456 void FieldRegion::dumpToStream(raw_ostream &os) const {
457 os << superRegion << "->" << *getDecl();
460 void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
461 os << "ivar{" << superRegion << ',' << *getDecl() << '}';
464 void StringRegion::dumpToStream(raw_ostream &os) const {
465 assert(Str != nullptr && "Expecting non-null StringLiteral");
466 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
469 void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
470 assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
471 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
474 void SymbolicRegion::dumpToStream(raw_ostream &os) const {
475 os << "SymRegion{" << sym << '}';
478 void VarRegion::dumpToStream(raw_ostream &os) const {
479 os << *cast<VarDecl>(D);
482 LLVM_DUMP_METHOD void RegionRawOffset::dump() const {
483 dumpToStream(llvm::errs());
486 void RegionRawOffset::dumpToStream(raw_ostream &os) const {
487 os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
490 void CodeSpaceRegion::dumpToStream(raw_ostream &os) const {
491 os << "CodeSpaceRegion";
494 void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
495 os << "StaticGlobalsMemSpace{" << CR << '}';
498 void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
499 os << "GlobalInternalSpaceRegion";
502 void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
503 os << "GlobalSystemSpaceRegion";
506 void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
507 os << "GlobalImmutableSpaceRegion";
510 void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
511 os << "HeapSpaceRegion";
514 void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
515 os << "UnknownSpaceRegion";
518 void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
519 os << "StackArgumentsSpaceRegion";
522 void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
523 os << "StackLocalsSpaceRegion";
526 bool MemRegion::canPrintPretty() const {
527 return canPrintPrettyAsExpr();
530 bool MemRegion::canPrintPrettyAsExpr() const {
534 void MemRegion::printPretty(raw_ostream &os) const {
535 assert(canPrintPretty() && "This region cannot be printed pretty.");
537 printPrettyAsExpr(os);
541 void MemRegion::printPrettyAsExpr(raw_ostream &os) const {
542 llvm_unreachable("This region cannot be printed pretty.");
545 bool VarRegion::canPrintPrettyAsExpr() const {
549 void VarRegion::printPrettyAsExpr(raw_ostream &os) const {
550 os << getDecl()->getName();
553 bool ObjCIvarRegion::canPrintPrettyAsExpr() const {
557 void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
558 os << getDecl()->getName();
561 bool FieldRegion::canPrintPretty() const {
565 bool FieldRegion::canPrintPrettyAsExpr() const {
566 return superRegion->canPrintPrettyAsExpr();
569 void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
570 assert(canPrintPrettyAsExpr());
571 superRegion->printPrettyAsExpr(os);
572 os << "." << getDecl()->getName();
575 void FieldRegion::printPretty(raw_ostream &os) const {
576 if (canPrintPrettyAsExpr()) {
578 printPrettyAsExpr(os);
581 os << "field " << "\'" << getDecl()->getName() << "'";
585 bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
586 return superRegion->canPrintPrettyAsExpr();
589 void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
590 superRegion->printPrettyAsExpr(os);
593 std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
594 std::string VariableName;
595 std::string ArrayIndices;
596 const MemRegion *R = this;
598 llvm::raw_svector_ostream os(buf);
600 // Obtain array indices to add them to the variable name.
601 const ElementRegion *ER = nullptr;
602 while ((ER = R->getAs<ElementRegion>())) {
603 // Index is a ConcreteInt.
604 if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
605 llvm::SmallString<2> Idx;
606 CI->getValue().toString(Idx);
607 ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
609 // If not a ConcreteInt, try to obtain the variable
610 // name by calling 'getDescriptiveName' recursively.
612 std::string Idx = ER->getDescriptiveName(false);
614 ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
617 R = ER->getSuperRegion();
620 // Get variable name.
621 if (R && R->canPrintPrettyAsExpr()) {
622 R->printPrettyAsExpr(os);
624 return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
626 return (llvm::Twine(os.str()) + ArrayIndices).str();
633 SourceRange MemRegion::sourceRange() const {
634 const VarRegion *const VR = dyn_cast<VarRegion>(this->getBaseRegion());
635 const FieldRegion *const FR = dyn_cast<FieldRegion>(this);
637 // Check for more specific regions first.
640 return FR->getDecl()->getSourceRange();
644 return VR->getDecl()->getSourceRange();
646 // Return invalid source range (can be checked by client).
648 return SourceRange{};
652 //===----------------------------------------------------------------------===//
653 // MemRegionManager methods.
654 //===----------------------------------------------------------------------===//
656 template <typename REG>
657 const REG *MemRegionManager::LazyAllocate(REG*& region) {
659 region = A.Allocate<REG>();
660 new (region) REG(this);
666 template <typename REG, typename ARG>
667 const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
669 region = A.Allocate<REG>();
670 new (region) REG(this, a);
676 const StackLocalsSpaceRegion*
677 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
679 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
684 R = A.Allocate<StackLocalsSpaceRegion>();
685 new (R) StackLocalsSpaceRegion(this, STC);
689 const StackArgumentsSpaceRegion *
690 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
692 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
697 R = A.Allocate<StackArgumentsSpaceRegion>();
698 new (R) StackArgumentsSpaceRegion(this, STC);
702 const GlobalsSpaceRegion
703 *MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
704 const CodeTextRegion *CR) {
706 if (K == MemRegion::GlobalSystemSpaceRegionKind)
707 return LazyAllocate(SystemGlobals);
708 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
709 return LazyAllocate(ImmutableGlobals);
710 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
711 return LazyAllocate(InternalGlobals);
714 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
715 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
719 R = A.Allocate<StaticGlobalSpaceRegion>();
720 new (R) StaticGlobalSpaceRegion(this, CR);
724 const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
725 return LazyAllocate(heap);
728 const UnknownSpaceRegion *MemRegionManager::getUnknownRegion() {
729 return LazyAllocate(unknown);
732 const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
733 return LazyAllocate(code);
736 //===----------------------------------------------------------------------===//
737 // Constructing regions.
738 //===----------------------------------------------------------------------===//
739 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
740 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
743 const ObjCStringRegion *
744 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
745 return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
748 /// Look through a chain of LocationContexts to either find the
749 /// StackFrameContext that matches a DeclContext, or find a VarRegion
750 /// for a variable captured by a block.
751 static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
752 getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
753 const DeclContext *DC,
756 if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
757 if (cast<DeclContext>(SFC->getDecl()) == DC)
760 if (const BlockInvocationContext *BC =
761 dyn_cast<BlockInvocationContext>(LC)) {
762 const BlockDataRegion *BR =
763 static_cast<const BlockDataRegion*>(BC->getContextData());
764 // FIXME: This can be made more efficient.
765 for (BlockDataRegion::referenced_vars_iterator
766 I = BR->referenced_vars_begin(),
767 E = BR->referenced_vars_end(); I != E; ++I) {
768 if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
769 if (VR->getDecl() == VD)
770 return cast<VarRegion>(I.getCapturedRegion());
774 LC = LC->getParent();
776 return (const StackFrameContext *)nullptr;
779 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
780 const LocationContext *LC) {
781 const MemRegion *sReg = nullptr;
783 if (D->hasGlobalStorage() && !D->isStaticLocal()) {
785 // First handle the globals defined in system headers.
786 if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
787 // Whitelist the system globals which often DO GET modified, assume the
788 // rest are immutable.
789 if (D->getName().find("errno") != StringRef::npos)
790 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
792 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
794 // Treat other globals as GlobalInternal unless they are constants.
796 QualType GQT = D->getType();
797 const Type *GT = GQT.getTypePtrOrNull();
798 // TODO: We could walk the complex types here and see if everything is
800 if (GT && GQT.isConstQualified() && GT->isArithmeticType())
801 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
803 sReg = getGlobalsRegion();
806 // Finally handle static locals.
808 // FIXME: Once we implement scope handling, we will need to properly lookup
809 // 'D' to the proper LocationContext.
810 const DeclContext *DC = D->getDeclContext();
811 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
812 getStackOrCaptureRegionForDeclContext(LC, DC, D);
814 if (V.is<const VarRegion*>())
815 return V.get<const VarRegion*>();
817 const StackFrameContext *STC = V.get<const StackFrameContext*>();
820 sReg = getUnknownRegion();
822 if (D->hasLocalStorage()) {
823 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
824 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
825 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
828 assert(D->isStaticLocal());
829 const Decl *STCD = STC->getDecl();
830 if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
831 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
832 getFunctionCodeRegion(cast<NamedDecl>(STCD)));
833 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
834 // FIXME: The fallback type here is totally bogus -- though it should
835 // never be queried, it will prevent uniquing with the real
836 // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
839 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
842 T = getContext().VoidTy;
843 if (!T->getAs<FunctionType>())
844 T = getContext().getFunctionNoProtoType(T);
845 T = getContext().getBlockPointerType(T);
847 const BlockCodeRegion *BTR =
848 getBlockCodeRegion(BD, C.getCanonicalType(T),
849 STC->getAnalysisDeclContext());
850 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
854 sReg = getGlobalsRegion();
860 return getSubRegion<VarRegion>(D, sReg);
863 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
864 const MemRegion *superR) {
865 return getSubRegion<VarRegion>(D, superR);
868 const BlockDataRegion *
869 MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
870 const LocationContext *LC,
871 unsigned blockCount) {
872 const MemRegion *sReg = nullptr;
873 const BlockDecl *BD = BC->getDecl();
874 if (!BD->hasCaptures()) {
875 // This handles 'static' blocks.
876 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
880 // FIXME: Once we implement scope handling, we want the parent region
882 const StackFrameContext *STC = LC->getCurrentStackFrame();
884 sReg = getStackLocalsRegion(STC);
887 // We allow 'LC' to be NULL for cases where want BlockDataRegions
888 // without context-sensitivity.
889 sReg = getUnknownRegion();
893 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
896 const CXXTempObjectRegion *
897 MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
898 return getSubRegion<CXXTempObjectRegion>(
899 Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
902 const CompoundLiteralRegion*
903 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
904 const LocationContext *LC) {
905 const MemRegion *sReg = nullptr;
907 if (CL->isFileScope())
908 sReg = getGlobalsRegion();
910 const StackFrameContext *STC = LC->getCurrentStackFrame();
912 sReg = getStackLocalsRegion(STC);
915 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
919 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
920 const MemRegion* superRegion,
922 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
924 llvm::FoldingSetNodeID ID;
925 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
928 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
929 ElementRegion* R = cast_or_null<ElementRegion>(data);
932 R = A.Allocate<ElementRegion>();
933 new (R) ElementRegion(T, Idx, superRegion);
934 Regions.InsertNode(R, InsertPos);
940 const FunctionCodeRegion *
941 MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) {
942 return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
945 const BlockCodeRegion *
946 MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy,
947 AnalysisDeclContext *AC) {
948 return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion());
952 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
953 const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
954 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
957 const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
958 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
962 MemRegionManager::getFieldRegion(const FieldDecl *d,
963 const MemRegion* superRegion){
964 return getSubRegion<FieldRegion>(d, superRegion);
967 const ObjCIvarRegion*
968 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
969 const MemRegion* superRegion) {
970 return getSubRegion<ObjCIvarRegion>(d, superRegion);
973 const CXXTempObjectRegion*
974 MemRegionManager::getCXXTempObjectRegion(Expr const *E,
975 LocationContext const *LC) {
976 const StackFrameContext *SFC = LC->getCurrentStackFrame();
978 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
981 /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
982 /// class of the type of \p Super.
983 static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
984 const TypedValueRegion *Super,
986 BaseClass = BaseClass->getCanonicalDecl();
988 const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
993 return Class->isVirtuallyDerivedFrom(BaseClass);
995 for (const auto &I : Class->bases()) {
996 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1003 const CXXBaseObjectRegion *
1004 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
1005 const MemRegion *Super,
1007 if (isa<TypedValueRegion>(Super)) {
1008 assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
1009 (void)&isValidBaseClass;
1012 // Virtual base regions should not be layered, since the layout rules
1014 while (const CXXBaseObjectRegion *Base =
1015 dyn_cast<CXXBaseObjectRegion>(Super)) {
1016 Super = Base->getSuperRegion();
1018 assert(Super && !isa<MemSpaceRegion>(Super));
1022 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1025 const CXXThisRegion*
1026 MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
1027 const LocationContext *LC) {
1028 const PointerType *PT = thisPointerTy->getAs<PointerType>();
1030 // Inside the body of the operator() of a lambda a this expr might refer to an
1031 // object in one of the parent location contexts.
1032 const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1033 // FIXME: when operator() of lambda is analyzed as a top level function and
1034 // 'this' refers to a this to the enclosing scope, there is no right region to
1036 while (!LC->inTopFrame() &&
1037 (!D || D->isStatic() ||
1038 PT != D->getThisType(getContext())->getAs<PointerType>())) {
1039 LC = LC->getParent();
1040 D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1042 const StackFrameContext *STC = LC->getCurrentStackFrame();
1044 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
1048 MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
1049 const LocationContext *LC) {
1050 const StackFrameContext *STC = LC->getCurrentStackFrame();
1052 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
1055 const MemSpaceRegion *MemRegion::getMemorySpace() const {
1056 const MemRegion *R = this;
1057 const SubRegion* SR = dyn_cast<SubRegion>(this);
1060 R = SR->getSuperRegion();
1061 SR = dyn_cast<SubRegion>(R);
1064 return dyn_cast<MemSpaceRegion>(R);
1067 bool MemRegion::hasStackStorage() const {
1068 return isa<StackSpaceRegion>(getMemorySpace());
1071 bool MemRegion::hasStackNonParametersStorage() const {
1072 return isa<StackLocalsSpaceRegion>(getMemorySpace());
1075 bool MemRegion::hasStackParametersStorage() const {
1076 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
1079 bool MemRegion::hasGlobalsOrParametersStorage() const {
1080 const MemSpaceRegion *MS = getMemorySpace();
1081 return isa<StackArgumentsSpaceRegion>(MS) ||
1082 isa<GlobalsSpaceRegion>(MS);
1085 // getBaseRegion strips away all elements and fields, and get the base region
1087 const MemRegion *MemRegion::getBaseRegion() const {
1088 const MemRegion *R = this;
1090 switch (R->getKind()) {
1091 case MemRegion::ElementRegionKind:
1092 case MemRegion::FieldRegionKind:
1093 case MemRegion::ObjCIvarRegionKind:
1094 case MemRegion::CXXBaseObjectRegionKind:
1095 R = cast<SubRegion>(R)->getSuperRegion();
1105 bool MemRegion::isSubRegionOf(const MemRegion *R) const {
1109 //===----------------------------------------------------------------------===//
1111 //===----------------------------------------------------------------------===//
1113 const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
1114 const MemRegion *R = this;
1116 switch (R->getKind()) {
1117 case ElementRegionKind: {
1118 const ElementRegion *ER = cast<ElementRegion>(R);
1119 if (!ER->getIndex().isZeroConstant())
1121 R = ER->getSuperRegion();
1124 case CXXBaseObjectRegionKind:
1125 if (!StripBaseCasts)
1127 R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
1135 const SymbolicRegion *MemRegion::getSymbolicBase() const {
1136 const SubRegion *SubR = dyn_cast<SubRegion>(this);
1139 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
1141 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1146 RegionRawOffset ElementRegion::getAsArrayOffset() const {
1147 CharUnits offset = CharUnits::Zero();
1148 const ElementRegion *ER = this;
1149 const MemRegion *superR = nullptr;
1150 ASTContext &C = getContext();
1152 // FIXME: Handle multi-dimensional arrays.
1155 superR = ER->getSuperRegion();
1157 // FIXME: generalize to symbolic offsets.
1158 SVal index = ER->getIndex();
1159 if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) {
1160 // Update the offset.
1161 int64_t i = CI->getValue().getSExtValue();
1164 QualType elemType = ER->getElementType();
1166 // If we are pointing to an incomplete type, go no further.
1167 if (elemType->isIncompleteType()) {
1172 CharUnits size = C.getTypeSizeInChars(elemType);
1173 offset += (i * size);
1176 // Go to the next ElementRegion (if any).
1177 ER = dyn_cast<ElementRegion>(superR);
1184 assert(superR && "super region cannot be NULL");
1185 return RegionRawOffset(superR, offset);
1189 /// Returns true if \p Base is an immediate base class of \p Child
1190 static bool isImmediateBase(const CXXRecordDecl *Child,
1191 const CXXRecordDecl *Base) {
1192 assert(Child && "Child must not be null");
1193 // Note that we do NOT canonicalize the base class here, because
1194 // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1195 // so be it; at least we won't crash.
1196 for (const auto &I : Child->bases()) {
1197 if (I.getType()->getAsCXXRecordDecl() == Base)
1204 RegionOffset MemRegion::getAsOffset() const {
1205 const MemRegion *R = this;
1206 const MemRegion *SymbolicOffsetBase = nullptr;
1210 switch (R->getKind()) {
1211 case CodeSpaceRegionKind:
1212 case StackLocalsSpaceRegionKind:
1213 case StackArgumentsSpaceRegionKind:
1214 case HeapSpaceRegionKind:
1215 case UnknownSpaceRegionKind:
1216 case StaticGlobalSpaceRegionKind:
1217 case GlobalInternalSpaceRegionKind:
1218 case GlobalSystemSpaceRegionKind:
1219 case GlobalImmutableSpaceRegionKind:
1220 // Stores can bind directly to a region space to set a default value.
1221 assert(Offset == 0 && !SymbolicOffsetBase);
1224 case FunctionCodeRegionKind:
1225 case BlockCodeRegionKind:
1226 case BlockDataRegionKind:
1227 // These will never have bindings, but may end up having values requested
1228 // if the user does some strange casting.
1230 SymbolicOffsetBase = R;
1233 case SymbolicRegionKind:
1234 case AllocaRegionKind:
1235 case CompoundLiteralRegionKind:
1236 case CXXThisRegionKind:
1237 case StringRegionKind:
1238 case ObjCStringRegionKind:
1240 case CXXTempObjectRegionKind:
1241 // Usual base regions.
1244 case ObjCIvarRegionKind:
1245 // This is a little strange, but it's a compromise between
1246 // ObjCIvarRegions having unknown compile-time offsets (when using the
1247 // non-fragile runtime) and yet still being distinct, non-overlapping
1248 // regions. Thus we treat them as "like" base regions for the purposes
1249 // of computing offsets.
1252 case CXXBaseObjectRegionKind: {
1253 const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
1254 R = BOR->getSuperRegion();
1257 bool RootIsSymbolic = false;
1258 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
1259 Ty = TVR->getDesugaredValueType(getContext());
1260 } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1261 // If our base region is symbolic, we don't know what type it really is.
1262 // Pretend the type of the symbol is the true dynamic type.
1263 // (This will at least be self-consistent for the life of the symbol.)
1264 Ty = SR->getSymbol()->getType()->getPointeeType();
1265 RootIsSymbolic = true;
1268 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1270 // We cannot compute the offset of the base class.
1271 SymbolicOffsetBase = R;
1273 if (RootIsSymbolic) {
1274 // Base layers on symbolic regions may not be type-correct.
1275 // Double-check the inheritance here, and revert to a symbolic offset
1276 // if it's invalid (e.g. due to a reinterpret_cast).
1277 if (BOR->isVirtual()) {
1278 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1279 SymbolicOffsetBase = R;
1281 if (!isImmediateBase(Child, BOR->getDecl()))
1282 SymbolicOffsetBase = R;
1287 // Don't bother calculating precise offsets if we already have a
1288 // symbolic offset somewhere in the chain.
1289 if (SymbolicOffsetBase)
1292 CharUnits BaseOffset;
1293 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
1294 if (BOR->isVirtual())
1295 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1297 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1299 // The base offset is in chars, not in bits.
1300 Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
1303 case ElementRegionKind: {
1304 const ElementRegion *ER = cast<ElementRegion>(R);
1305 R = ER->getSuperRegion();
1307 QualType EleTy = ER->getValueType();
1308 if (EleTy->isIncompleteType()) {
1309 // We cannot compute the offset of the base class.
1310 SymbolicOffsetBase = R;
1314 SVal Index = ER->getIndex();
1315 if (Optional<nonloc::ConcreteInt> CI =
1316 Index.getAs<nonloc::ConcreteInt>()) {
1317 // Don't bother calculating precise offsets if we already have a
1318 // symbolic offset somewhere in the chain.
1319 if (SymbolicOffsetBase)
1322 int64_t i = CI->getValue().getSExtValue();
1323 // This type size is in bits.
1324 Offset += i * getContext().getTypeSize(EleTy);
1326 // We cannot compute offset for non-concrete index.
1327 SymbolicOffsetBase = R;
1331 case FieldRegionKind: {
1332 const FieldRegion *FR = cast<FieldRegion>(R);
1333 R = FR->getSuperRegion();
1335 const RecordDecl *RD = FR->getDecl()->getParent();
1336 if (RD->isUnion() || !RD->isCompleteDefinition()) {
1337 // We cannot compute offset for incomplete type.
1338 // For unions, we could treat everything as offset 0, but we'd rather
1339 // treat each field as a symbolic offset so they aren't stored on top
1340 // of each other, since we depend on things in typed regions actually
1341 // matching their types.
1342 SymbolicOffsetBase = R;
1345 // Don't bother calculating precise offsets if we already have a
1346 // symbolic offset somewhere in the chain.
1347 if (SymbolicOffsetBase)
1350 // Get the field number.
1352 for (RecordDecl::field_iterator FI = RD->field_begin(),
1353 FE = RD->field_end(); FI != FE; ++FI, ++idx) {
1354 if (FR->getDecl() == *FI)
1357 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1358 // This is offset in bits.
1359 Offset += Layout.getFieldOffset(idx);
1366 if (SymbolicOffsetBase)
1367 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1368 return RegionOffset(R, Offset);
1371 //===----------------------------------------------------------------------===//
1373 //===----------------------------------------------------------------------===//
1375 std::pair<const VarRegion *, const VarRegion *>
1376 BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1377 MemRegionManager &MemMgr = *getMemRegionManager();
1378 const VarRegion *VR = nullptr;
1379 const VarRegion *OriginalVR = nullptr;
1381 if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1382 VR = MemMgr.getVarRegion(VD, this);
1383 OriginalVR = MemMgr.getVarRegion(VD, LC);
1387 VR = MemMgr.getVarRegion(VD, LC);
1391 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
1392 OriginalVR = MemMgr.getVarRegion(VD, LC);
1395 return std::make_pair(VR, OriginalVR);
1398 void BlockDataRegion::LazyInitializeReferencedVars() {
1402 AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
1403 const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
1405 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1407 if (NumBlockVars == 0) {
1408 ReferencedVars = (void*) 0x1;
1412 MemRegionManager &MemMgr = *getMemRegionManager();
1413 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1414 BumpVectorContext BC(A);
1416 typedef BumpVector<const MemRegion*> VarVec;
1417 VarVec *BV = A.Allocate<VarVec>();
1418 new (BV) VarVec(BC, NumBlockVars);
1419 VarVec *BVOriginal = A.Allocate<VarVec>();
1420 new (BVOriginal) VarVec(BC, NumBlockVars);
1422 for (const VarDecl *VD : ReferencedBlockVars) {
1423 const VarRegion *VR = nullptr;
1424 const VarRegion *OriginalVR = nullptr;
1425 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1428 BV->push_back(VR, BC);
1429 BVOriginal->push_back(OriginalVR, BC);
1432 ReferencedVars = BV;
1433 OriginalVars = BVOriginal;
1436 BlockDataRegion::referenced_vars_iterator
1437 BlockDataRegion::referenced_vars_begin() const {
1438 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1440 BumpVector<const MemRegion*> *Vec =
1441 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1443 if (Vec == (void*) 0x1)
1444 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1446 BumpVector<const MemRegion*> *VecOriginal =
1447 static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1449 return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
1450 VecOriginal->begin());
1453 BlockDataRegion::referenced_vars_iterator
1454 BlockDataRegion::referenced_vars_end() const {
1455 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1457 BumpVector<const MemRegion*> *Vec =
1458 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1460 if (Vec == (void*) 0x1)
1461 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1463 BumpVector<const MemRegion*> *VecOriginal =
1464 static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1466 return BlockDataRegion::referenced_vars_iterator(Vec->end(),
1467 VecOriginal->end());
1470 const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
1471 for (referenced_vars_iterator I = referenced_vars_begin(),
1472 E = referenced_vars_end();
1474 if (I.getCapturedRegion() == R)
1475 return I.getOriginalRegion();
1480 //===----------------------------------------------------------------------===//
1481 // RegionAndSymbolInvalidationTraits
1482 //===----------------------------------------------------------------------===//
1484 void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
1485 InvalidationKinds IK) {
1486 SymTraitsMap[Sym] |= IK;
1489 void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
1490 InvalidationKinds IK) {
1492 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1493 setTrait(SR->getSymbol(), IK);
1495 MRTraitsMap[MR] |= IK;
1498 bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
1499 InvalidationKinds IK) const {
1500 const_symbol_iterator I = SymTraitsMap.find(Sym);
1501 if (I != SymTraitsMap.end())
1502 return I->second & IK;
1507 bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
1508 InvalidationKinds IK) const {
1512 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1513 return hasTrait(SR->getSymbol(), IK);
1515 const_region_iterator I = MRTraitsMap.find(MR);
1516 if (I != MRTraitsMap.end())
1517 return I->second & IK;