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