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