Bug Summary

File:tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Warning:line 1442, column 39
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MemRegion.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/lib/StaticAnalyzer/Core -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/StaticAnalyzer/Core -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/lib/StaticAnalyzer/Core -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp

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

/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h

1//==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines MemRegion and its subclasses. MemRegion defines a
11// partially-typed abstraction of memory useful for path-sensitive dataflow
12// analyses.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
17#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
18
19#include "clang/AST/ASTContext.h"
20#include "clang/AST/CharUnits.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/DeclarationName.h"
24#include "clang/AST/Expr.h"
25#include "clang/AST/ExprObjC.h"
26#include "clang/AST/Type.h"
27#include "clang/Basic/LLVM.h"
28#include "clang/Basic/SourceLocation.h"
29#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
30#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
31#include "llvm/ADT/DenseMap.h"
32#include "llvm/ADT/FoldingSet.h"
33#include "llvm/ADT/Optional.h"
34#include "llvm/ADT/PointerIntPair.h"
35#include "llvm/Support/Allocator.h"
36#include "llvm/Support/Casting.h"
37#include <cassert>
38#include <cstdint>
39#include <limits>
40#include <string>
41#include <utility>
42
43namespace clang {
44
45class AnalysisDeclContext;
46class CXXRecordDecl;
47class Decl;
48class LocationContext;
49class StackFrameContext;
50
51namespace ento {
52
53class CodeTextRegion;
54class MemRegion;
55class MemRegionManager;
56class MemSpaceRegion;
57class SValBuilder;
58class SymbolicRegion;
59class VarRegion;
60
61/// Represent a region's offset within the top level base region.
62class RegionOffset {
63 /// The base region.
64 const MemRegion *R = nullptr;
65
66 /// The bit offset within the base region. Can be negative.
67 int64_t Offset;
68
69public:
70 // We're using a const instead of an enumeration due to the size required;
71 // Visual Studio will only create enumerations of size int, not long long.
72 static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
73
74 RegionOffset() = default;
75 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
76
77 const MemRegion *getRegion() const { return R; }
78
79 bool hasSymbolicOffset() const { return Offset == Symbolic; }
80
81 int64_t getOffset() const {
82 assert(!hasSymbolicOffset())((!hasSymbolicOffset()) ? static_cast<void> (0) : __assert_fail
("!hasSymbolicOffset()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 82, __PRETTY_FUNCTION__))
;
83 return Offset;
84 }
85
86 bool isValid() const { return R; }
87};
88
89//===----------------------------------------------------------------------===//
90// Base region classes.
91//===----------------------------------------------------------------------===//
92
93/// MemRegion - The root abstract class for all memory regions.
94class MemRegion : public llvm::FoldingSetNode {
95public:
96 enum Kind {
97#define REGION(Id, Parent) Id ## Kind,
98#define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
99#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
100 };
101
102private:
103 const Kind kind;
104 mutable Optional<RegionOffset> cachedOffset;
105
106protected:
107 MemRegion(Kind k) : kind(k) {}
108 virtual ~MemRegion();
109
110public:
111 ASTContext &getContext() const;
112
113 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
114
115 virtual MemRegionManager* getMemRegionManager() const = 0;
116
117 const MemSpaceRegion *getMemorySpace() const;
118
119 const MemRegion *getBaseRegion() const;
120
121 /// Check if the region is a subregion of the given region.
122 /// Each region is a subregion of itself.
123 virtual bool isSubRegionOf(const MemRegion *R) const;
124
125 const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
126
127 /// If this is a symbolic region, returns the region. Otherwise,
128 /// goes up the base chain looking for the first symbolic base region.
129 const SymbolicRegion *getSymbolicBase() const;
130
131 bool hasGlobalsOrParametersStorage() const;
132
133 bool hasStackStorage() const;
134
135 bool hasStackNonParametersStorage() const;
136
137 bool hasStackParametersStorage() const;
138
139 /// Compute the offset within the top level memory object.
140 RegionOffset getAsOffset() const;
141
142 /// Get a string representation of a region for debug use.
143 std::string getString() const;
144
145 virtual void dumpToStream(raw_ostream &os) const;
146
147 void dump() const;
148
149 /// Returns true if this region can be printed in a user-friendly way.
150 virtual bool canPrintPretty() const;
151
152 /// Print the region for use in diagnostics.
153 virtual void printPretty(raw_ostream &os) const;
154
155 /// Returns true if this region's textual representation can be used
156 /// as part of a larger expression.
157 virtual bool canPrintPrettyAsExpr() const;
158
159 /// Print the region as expression.
160 ///
161 /// When this region represents a subexpression, the method is for printing
162 /// an expression containing it.
163 virtual void printPrettyAsExpr(raw_ostream &os) const;
164
165 Kind getKind() const { return kind; }
166
167 template<typename RegionTy> const RegionTy* getAs() const;
168
169 virtual bool isBoundable() const { return false; }
170
171 /// Get descriptive name for memory region. The name is obtained from
172 /// the variable/field declaration retrieved from the memory region.
173 /// Regions that point to an element of an array are returned as: "arr[0]".
174 /// Regions that point to a struct are returned as: "st.var".
175 //
176 /// \param UseQuotes Set if the name should be quoted.
177 ///
178 /// \returns variable name for memory region
179 std::string getDescriptiveName(bool UseQuotes = true) const;
180
181 /// Retrieve source range from memory region. The range retrieval
182 /// is based on the decl obtained from the memory region.
183 /// For a VarRegion the range of the base region is returned.
184 /// For a FieldRegion the range of the field is returned.
185 /// If no declaration is found, an empty source range is returned.
186 /// The client is responsible for checking if the returned range is valid.
187 ///
188 /// \returns source range for declaration retrieved from memory region
189 SourceRange sourceRange() const;
190};
191
192/// MemSpaceRegion - A memory region that represents a "memory space";
193/// for example, the set of global variables, the stack frame, etc.
194class MemSpaceRegion : public MemRegion {
195protected:
196 MemRegionManager *Mgr;
197
198 MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
199 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 199, __PRETTY_FUNCTION__))
;
200 assert(mgr)((mgr) ? static_cast<void> (0) : __assert_fail ("mgr", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 200, __PRETTY_FUNCTION__))
;
201 }
202
203 MemRegionManager* getMemRegionManager() const override { return Mgr; }
204
205public:
206 bool isBoundable() const override { return false; }
207
208 void Profile(llvm::FoldingSetNodeID &ID) const override;
209
210 static bool classof(const MemRegion *R) {
211 Kind k = R->getKind();
212 return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
213 }
214};
215
216/// CodeSpaceRegion - The memory space that holds the executable code of
217/// functions and blocks.
218class CodeSpaceRegion : public MemSpaceRegion {
219 friend class MemRegionManager;
220
221 CodeSpaceRegion(MemRegionManager *mgr)
222 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
223
224public:
225 void dumpToStream(raw_ostream &os) const override;
226
227 static bool classof(const MemRegion *R) {
228 return R->getKind() == CodeSpaceRegionKind;
229 }
230};
231
232class GlobalsSpaceRegion : public MemSpaceRegion {
233 virtual void anchor();
234
235protected:
236 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
237 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 237, __PRETTY_FUNCTION__))
;
238 }
239
240public:
241 static bool classof(const MemRegion *R) {
242 Kind k = R->getKind();
243 return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
244 }
245};
246
247/// The region of the static variables within the current CodeTextRegion
248/// scope.
249///
250/// Currently, only the static locals are placed there, so we know that these
251/// variables do not get invalidated by calls to other functions.
252class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
253 friend class MemRegionManager;
254
255 const CodeTextRegion *CR;
256
257 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
258 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
259 assert(cr)((cr) ? static_cast<void> (0) : __assert_fail ("cr", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 259, __PRETTY_FUNCTION__))
;
260 }
261
262public:
263 void Profile(llvm::FoldingSetNodeID &ID) const override;
264
265 void dumpToStream(raw_ostream &os) const override;
266
267 const CodeTextRegion *getCodeRegion() const { return CR; }
268
269 static bool classof(const MemRegion *R) {
270 return R->getKind() == StaticGlobalSpaceRegionKind;
271 }
272};
273
274/// The region for all the non-static global variables.
275///
276/// This class is further split into subclasses for efficient implementation of
277/// invalidating a set of related global values as is done in
278/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
279/// globals, we invalidate the whole parent region).
280class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
281 void anchor() override;
282
283protected:
284 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
285 : GlobalsSpaceRegion(mgr, k) {
286 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 286, __PRETTY_FUNCTION__))
;
287 }
288
289public:
290 static bool classof(const MemRegion *R) {
291 Kind k = R->getKind();
292 return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
293 k <= END_NON_STATIC_GLOBAL_MEMSPACES;
294 }
295};
296
297/// The region containing globals which are defined in system/external
298/// headers and are considered modifiable by system calls (ex: errno).
299class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
300 friend class MemRegionManager;
301
302 GlobalSystemSpaceRegion(MemRegionManager *mgr)
303 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
304
305public:
306 void dumpToStream(raw_ostream &os) const override;
307
308 static bool classof(const MemRegion *R) {
309 return R->getKind() == GlobalSystemSpaceRegionKind;
310 }
311};
312
313/// The region containing globals which are considered not to be modified
314/// or point to data which could be modified as a result of a function call
315/// (system or internal). Ex: Const global scalars would be modeled as part of
316/// this region. This region also includes most system globals since they have
317/// low chance of being modified.
318class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
319 friend class MemRegionManager;
320
321 GlobalImmutableSpaceRegion(MemRegionManager *mgr)
322 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
323
324public:
325 void dumpToStream(raw_ostream &os) const override;
326
327 static bool classof(const MemRegion *R) {
328 return R->getKind() == GlobalImmutableSpaceRegionKind;
329 }
330};
331
332/// The region containing globals which can be modified by calls to
333/// "internally" defined functions - (for now just) functions other then system
334/// calls.
335class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
336 friend class MemRegionManager;
337
338 GlobalInternalSpaceRegion(MemRegionManager *mgr)
339 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
340
341public:
342 void dumpToStream(raw_ostream &os) const override;
343
344 static bool classof(const MemRegion *R) {
345 return R->getKind() == GlobalInternalSpaceRegionKind;
346 }
347};
348
349class HeapSpaceRegion : public MemSpaceRegion {
350 friend class MemRegionManager;
351
352 HeapSpaceRegion(MemRegionManager *mgr)
353 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
354
355public:
356 void dumpToStream(raw_ostream &os) const override;
357
358 static bool classof(const MemRegion *R) {
359 return R->getKind() == HeapSpaceRegionKind;
360 }
361};
362
363class UnknownSpaceRegion : public MemSpaceRegion {
364 friend class MemRegionManager;
365
366 UnknownSpaceRegion(MemRegionManager *mgr)
367 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
368
369public:
370 void dumpToStream(raw_ostream &os) const override;
371
372 static bool classof(const MemRegion *R) {
373 return R->getKind() == UnknownSpaceRegionKind;
374 }
375};
376
377class StackSpaceRegion : public MemSpaceRegion {
378 virtual void anchor();
379
380 const StackFrameContext *SFC;
381
382protected:
383 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
384 : MemSpaceRegion(mgr, k), SFC(sfc) {
385 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 385, __PRETTY_FUNCTION__))
;
386 assert(sfc)((sfc) ? static_cast<void> (0) : __assert_fail ("sfc", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 386, __PRETTY_FUNCTION__))
;
387 }
388
389public:
390 const StackFrameContext *getStackFrame() const { return SFC; }
391
392 void Profile(llvm::FoldingSetNodeID &ID) const override;
393
394 static bool classof(const MemRegion *R) {
395 Kind k = R->getKind();
396 return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
397 }
398};
399
400class StackLocalsSpaceRegion : public StackSpaceRegion {
401 friend class MemRegionManager;
402
403 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
404 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
405
406public:
407 void dumpToStream(raw_ostream &os) const override;
408
409 static bool classof(const MemRegion *R) {
410 return R->getKind() == StackLocalsSpaceRegionKind;
411 }
412};
413
414class StackArgumentsSpaceRegion : public StackSpaceRegion {
415private:
416 friend class MemRegionManager;
417
418 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
419 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
420
421public:
422 void dumpToStream(raw_ostream &os) const override;
423
424 static bool classof(const MemRegion *R) {
425 return R->getKind() == StackArgumentsSpaceRegionKind;
426 }
427};
428
429/// SubRegion - A region that subsets another larger region. Most regions
430/// are subclasses of SubRegion.
431class SubRegion : public MemRegion {
432 virtual void anchor();
433
434protected:
435 const MemRegion* superRegion;
436
437 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
438 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 438, __PRETTY_FUNCTION__))
;
439 assert(sReg)((sReg) ? static_cast<void> (0) : __assert_fail ("sReg"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 439, __PRETTY_FUNCTION__))
;
440 }
441
442public:
443 const MemRegion* getSuperRegion() const {
444 return superRegion;
7
Returning pointer
445 }
446
447 /// getExtent - Returns the size of the region in bytes.
448 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
449 return UnknownVal();
450 }
451
452 MemRegionManager* getMemRegionManager() const override;
453
454 bool isSubRegionOf(const MemRegion* R) const override;
455
456 static bool classof(const MemRegion* R) {
457 return R->getKind() > END_MEMSPACES;
458 }
459};
460
461//===----------------------------------------------------------------------===//
462// MemRegion subclasses.
463//===----------------------------------------------------------------------===//
464
465/// AllocaRegion - A region that represents an untyped blob of bytes created
466/// by a call to 'alloca'.
467class AllocaRegion : public SubRegion {
468 friend class MemRegionManager;
469
470 // Block counter. Used to distinguish different pieces of memory allocated by
471 // alloca at the same call site.
472 unsigned Cnt;
473
474 const Expr *Ex;
475
476 AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
477 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
478 assert(Ex)((Ex) ? static_cast<void> (0) : __assert_fail ("Ex", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 478, __PRETTY_FUNCTION__))
;
479 }
480
481 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
482 unsigned Cnt, const MemRegion *superRegion);
483
484public:
485 const Expr *getExpr() const { return Ex; }
486
487 bool isBoundable() const override { return true; }
488
489 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
490
491 void Profile(llvm::FoldingSetNodeID& ID) const override;
492
493 void dumpToStream(raw_ostream &os) const override;
494
495 static bool classof(const MemRegion* R) {
496 return R->getKind() == AllocaRegionKind;
497 }
498};
499
500/// TypedRegion - An abstract class representing regions that are typed.
501class TypedRegion : public SubRegion {
502 void anchor() override;
503
504protected:
505 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
506 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 506, __PRETTY_FUNCTION__))
;
507 }
508
509public:
510 virtual QualType getLocationType() const = 0;
511
512 QualType getDesugaredLocationType(ASTContext &Context) const {
513 return getLocationType().getDesugaredType(Context);
514 }
515
516 bool isBoundable() const override { return true; }
517
518 static bool classof(const MemRegion* R) {
519 unsigned k = R->getKind();
520 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
521 }
522};
523
524/// TypedValueRegion - An abstract class representing regions having a typed value.
525class TypedValueRegion : public TypedRegion {
526 void anchor() override;
527
528protected:
529 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
530 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 530, __PRETTY_FUNCTION__))
;
531 }
532
533public:
534 virtual QualType getValueType() const = 0;
535
536 QualType getLocationType() const override {
537 // FIXME: We can possibly optimize this later to cache this value.
538 QualType T = getValueType();
539 ASTContext &ctx = getContext();
540 if (T->getAs<ObjCObjectType>())
541 return ctx.getObjCObjectPointerType(T);
542 return ctx.getPointerType(getValueType());
543 }
544
545 QualType getDesugaredValueType(ASTContext &Context) const {
546 QualType T = getValueType();
547 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
548 }
549
550 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
551
552 static bool classof(const MemRegion* R) {
553 unsigned k = R->getKind();
554 return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
555 }
556};
557
558class CodeTextRegion : public TypedRegion {
559 void anchor() override;
560
561protected:
562 CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
563 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 563, __PRETTY_FUNCTION__))
;
564 }
565
566public:
567 bool isBoundable() const override { return false; }
568
569 static bool classof(const MemRegion* R) {
570 Kind k = R->getKind();
571 return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
572 }
573};
574
575/// FunctionCodeRegion - A region that represents code texts of function.
576class FunctionCodeRegion : public CodeTextRegion {
577 friend class MemRegionManager;
578
579 const NamedDecl *FD;
580
581 FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
582 : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
583 assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd))((isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd
)) ? static_cast<void> (0) : __assert_fail ("isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 583, __PRETTY_FUNCTION__))
;
584 }
585
586 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
587 const MemRegion*);
588
589public:
590 QualType getLocationType() const override {
591 const ASTContext &Ctx = getContext();
592 if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
593 return Ctx.getPointerType(D->getType());
594 }
595
596 assert(isa<ObjCMethodDecl>(FD))((isa<ObjCMethodDecl>(FD)) ? static_cast<void> (0
) : __assert_fail ("isa<ObjCMethodDecl>(FD)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 596, __PRETTY_FUNCTION__))
;
597 assert(false && "Getting the type of ObjCMethod is not supported yet")((false && "Getting the type of ObjCMethod is not supported yet"
) ? static_cast<void> (0) : __assert_fail ("false && \"Getting the type of ObjCMethod is not supported yet\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 597, __PRETTY_FUNCTION__))
;
598
599 // TODO: We might want to return a different type here (ex: id (*ty)(...))
600 // depending on how it is used.
601 return {};
602 }
603
604 const NamedDecl *getDecl() const {
605 return FD;
606 }
607
608 void dumpToStream(raw_ostream &os) const override;
609
610 void Profile(llvm::FoldingSetNodeID& ID) const override;
611
612 static bool classof(const MemRegion* R) {
613 return R->getKind() == FunctionCodeRegionKind;
614 }
615};
616
617/// BlockCodeRegion - A region that represents code texts of blocks (closures).
618/// Blocks are represented with two kinds of regions. BlockCodeRegions
619/// represent the "code", while BlockDataRegions represent instances of blocks,
620/// which correspond to "code+data". The distinction is important, because
621/// like a closure a block captures the values of externally referenced
622/// variables.
623class BlockCodeRegion : public CodeTextRegion {
624 friend class MemRegionManager;
625
626 const BlockDecl *BD;
627 AnalysisDeclContext *AC;
628 CanQualType locTy;
629
630 BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
631 AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
632 : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
633 assert(bd)((bd) ? static_cast<void> (0) : __assert_fail ("bd", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 633, __PRETTY_FUNCTION__))
;
634 assert(ac)((ac) ? static_cast<void> (0) : __assert_fail ("ac", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 634, __PRETTY_FUNCTION__))
;
635 assert(lTy->getTypePtr()->isBlockPointerType())((lTy->getTypePtr()->isBlockPointerType()) ? static_cast
<void> (0) : __assert_fail ("lTy->getTypePtr()->isBlockPointerType()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 635, __PRETTY_FUNCTION__))
;
636 }
637
638 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
639 CanQualType, const AnalysisDeclContext*,
640 const MemRegion*);
641
642public:
643 QualType getLocationType() const override {
644 return locTy;
645 }
646
647 const BlockDecl *getDecl() const {
648 return BD;
649 }
650
651 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
652
653 void dumpToStream(raw_ostream &os) const override;
654
655 void Profile(llvm::FoldingSetNodeID& ID) const override;
656
657 static bool classof(const MemRegion* R) {
658 return R->getKind() == BlockCodeRegionKind;
659 }
660};
661
662/// BlockDataRegion - A region that represents a block instance.
663/// Blocks are represented with two kinds of regions. BlockCodeRegions
664/// represent the "code", while BlockDataRegions represent instances of blocks,
665/// which correspond to "code+data". The distinction is important, because
666/// like a closure a block captures the values of externally referenced
667/// variables.
668class BlockDataRegion : public TypedRegion {
669 friend class MemRegionManager;
670
671 const BlockCodeRegion *BC;
672 const LocationContext *LC; // Can be null
673 unsigned BlockCount;
674 void *ReferencedVars = nullptr;
675 void *OriginalVars = nullptr;
676
677 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
678 unsigned count, const MemSpaceRegion *sreg)
679 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
680 BlockCount(count) {
681 assert(bc)((bc) ? static_cast<void> (0) : __assert_fail ("bc", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 681, __PRETTY_FUNCTION__))
;
682 assert(lc)((lc) ? static_cast<void> (0) : __assert_fail ("lc", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 682, __PRETTY_FUNCTION__))
;
683 assert(isa<GlobalImmutableSpaceRegion>(sreg) ||((isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion
>(sreg) || isa<UnknownSpaceRegion>(sreg)) ? static_cast
<void> (0) : __assert_fail ("isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion>(sreg) || isa<UnknownSpaceRegion>(sreg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 685, __PRETTY_FUNCTION__))
684 isa<StackLocalsSpaceRegion>(sreg) ||((isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion
>(sreg) || isa<UnknownSpaceRegion>(sreg)) ? static_cast
<void> (0) : __assert_fail ("isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion>(sreg) || isa<UnknownSpaceRegion>(sreg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 685, __PRETTY_FUNCTION__))
685 isa<UnknownSpaceRegion>(sreg))((isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion
>(sreg) || isa<UnknownSpaceRegion>(sreg)) ? static_cast
<void> (0) : __assert_fail ("isa<GlobalImmutableSpaceRegion>(sreg) || isa<StackLocalsSpaceRegion>(sreg) || isa<UnknownSpaceRegion>(sreg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 685, __PRETTY_FUNCTION__))
;
686 }
687
688 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
689 const LocationContext *, unsigned,
690 const MemRegion *);
691
692public:
693 const BlockCodeRegion *getCodeRegion() const { return BC; }
694
695 const BlockDecl *getDecl() const { return BC->getDecl(); }
696
697 QualType getLocationType() const override { return BC->getLocationType(); }
698
699 class referenced_vars_iterator {
700 const MemRegion * const *R;
701 const MemRegion * const *OriginalR;
702
703 public:
704 explicit referenced_vars_iterator(const MemRegion * const *r,
705 const MemRegion * const *originalR)
706 : R(r), OriginalR(originalR) {}
707
708 const VarRegion *getCapturedRegion() const {
709 return cast<VarRegion>(*R);
710 }
711
712 const VarRegion *getOriginalRegion() const {
713 return cast<VarRegion>(*OriginalR);
714 }
715
716 bool operator==(const referenced_vars_iterator &I) const {
717 assert((R == nullptr) == (I.R == nullptr))(((R == nullptr) == (I.R == nullptr)) ? static_cast<void>
(0) : __assert_fail ("(R == nullptr) == (I.R == nullptr)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 717, __PRETTY_FUNCTION__))
;
718 return I.R == R;
719 }
720
721 bool operator!=(const referenced_vars_iterator &I) const {
722 assert((R == nullptr) == (I.R == nullptr))(((R == nullptr) == (I.R == nullptr)) ? static_cast<void>
(0) : __assert_fail ("(R == nullptr) == (I.R == nullptr)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 722, __PRETTY_FUNCTION__))
;
723 return I.R != R;
724 }
725
726 referenced_vars_iterator &operator++() {
727 ++R;
728 ++OriginalR;
729 return *this;
730 }
731 };
732
733 /// Return the original region for a captured region, if
734 /// one exists.
735 const VarRegion *getOriginalRegion(const VarRegion *VR) const;
736
737 referenced_vars_iterator referenced_vars_begin() const;
738 referenced_vars_iterator referenced_vars_end() const;
739
740 void dumpToStream(raw_ostream &os) const override;
741
742 void Profile(llvm::FoldingSetNodeID& ID) const override;
743
744 static bool classof(const MemRegion* R) {
745 return R->getKind() == BlockDataRegionKind;
746 }
747
748private:
749 void LazyInitializeReferencedVars();
750 std::pair<const VarRegion *, const VarRegion *>
751 getCaptureRegions(const VarDecl *VD);
752};
753
754/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
755/// classes, SymbolicRegion represents a region that serves as an alias for
756/// either a real region, a NULL pointer, etc. It essentially is used to
757/// map the concept of symbolic values into the domain of regions. Symbolic
758/// regions do not need to be typed.
759class SymbolicRegion : public SubRegion {
760 friend class MemRegionManager;
761
762 const SymbolRef sym;
763
764 SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
765 : SubRegion(sreg, SymbolicRegionKind), sym(s) {
766 // Because pointer arithmetic is represented by ElementRegion layers,
767 // the base symbol here should not contain any arithmetic.
768 assert(s && isa<SymbolData>(s))((s && isa<SymbolData>(s)) ? static_cast<void
> (0) : __assert_fail ("s && isa<SymbolData>(s)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 768, __PRETTY_FUNCTION__))
;
769 assert(s->getType()->isAnyPointerType() ||((s->getType()->isAnyPointerType() || s->getType()->
isReferenceType() || s->getType()->isBlockPointerType()
) ? static_cast<void> (0) : __assert_fail ("s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 771, __PRETTY_FUNCTION__))
770 s->getType()->isReferenceType() ||((s->getType()->isAnyPointerType() || s->getType()->
isReferenceType() || s->getType()->isBlockPointerType()
) ? static_cast<void> (0) : __assert_fail ("s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 771, __PRETTY_FUNCTION__))
771 s->getType()->isBlockPointerType())((s->getType()->isAnyPointerType() || s->getType()->
isReferenceType() || s->getType()->isBlockPointerType()
) ? static_cast<void> (0) : __assert_fail ("s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 771, __PRETTY_FUNCTION__))
;
772
773 // populateWorklistFromSymbol() relies on this assertion, and needs to be
774 // updated if more cases are introduced.
775 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg))((isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion
>(sreg)) ? static_cast<void> (0) : __assert_fail ("isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 775, __PRETTY_FUNCTION__))
;
776 }
777
778public:
779 SymbolRef getSymbol() const { return sym; }
780
781 bool isBoundable() const override { return true; }
782
783 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
784
785 void Profile(llvm::FoldingSetNodeID& ID) const override;
786
787 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
788 SymbolRef sym,
789 const MemRegion* superRegion);
790
791 void dumpToStream(raw_ostream &os) const override;
792
793 static bool classof(const MemRegion* R) {
794 return R->getKind() == SymbolicRegionKind;
795 }
796};
797
798/// StringRegion - Region associated with a StringLiteral.
799class StringRegion : public TypedValueRegion {
800 friend class MemRegionManager;
801
802 const StringLiteral *Str;
803
804 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
805 : TypedValueRegion(sreg, StringRegionKind), Str(str) {
806 assert(str)((str) ? static_cast<void> (0) : __assert_fail ("str", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 806, __PRETTY_FUNCTION__))
;
807 }
808
809 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
810 const StringLiteral *Str,
811 const MemRegion *superRegion);
812
813public:
814 const StringLiteral *getStringLiteral() const { return Str; }
815
816 QualType getValueType() const override { return Str->getType(); }
817
818 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
819
820 bool isBoundable() const override { return false; }
821
822 void Profile(llvm::FoldingSetNodeID& ID) const override {
823 ProfileRegion(ID, Str, superRegion);
824 }
825
826 void dumpToStream(raw_ostream &os) const override;
827
828 static bool classof(const MemRegion* R) {
829 return R->getKind() == StringRegionKind;
830 }
831};
832
833/// The region associated with an ObjCStringLiteral.
834class ObjCStringRegion : public TypedValueRegion {
835 friend class MemRegionManager;
836
837 const ObjCStringLiteral *Str;
838
839 ObjCStringRegion(const ObjCStringLiteral *str,
840 const GlobalInternalSpaceRegion *sreg)
841 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
842 assert(str)((str) ? static_cast<void> (0) : __assert_fail ("str", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 842, __PRETTY_FUNCTION__))
;
843 }
844
845 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
846 const ObjCStringLiteral *Str,
847 const MemRegion *superRegion);
848
849public:
850 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
851
852 QualType getValueType() const override { return Str->getType(); }
853
854 bool isBoundable() const override { return false; }
855
856 void Profile(llvm::FoldingSetNodeID& ID) const override {
857 ProfileRegion(ID, Str, superRegion);
858 }
859
860 void dumpToStream(raw_ostream &os) const override;
861
862 static bool classof(const MemRegion* R) {
863 return R->getKind() == ObjCStringRegionKind;
864 }
865};
866
867/// CompoundLiteralRegion - A memory region representing a compound literal.
868/// Compound literals are essentially temporaries that are stack allocated
869/// or in the global constant pool.
870class CompoundLiteralRegion : public TypedValueRegion {
871 friend class MemRegionManager;
872
873 const CompoundLiteralExpr *CL;
874
875 CompoundLiteralRegion(const CompoundLiteralExpr *cl,
876 const MemSpaceRegion *sReg)
877 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
878 assert(cl)((cl) ? static_cast<void> (0) : __assert_fail ("cl", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 878, __PRETTY_FUNCTION__))
;
879 assert(isa<GlobalInternalSpaceRegion>(sReg) ||((isa<GlobalInternalSpaceRegion>(sReg) || isa<StackLocalsSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<GlobalInternalSpaceRegion>(sReg) || isa<StackLocalsSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 880, __PRETTY_FUNCTION__))
880 isa<StackLocalsSpaceRegion>(sReg))((isa<GlobalInternalSpaceRegion>(sReg) || isa<StackLocalsSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<GlobalInternalSpaceRegion>(sReg) || isa<StackLocalsSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 880, __PRETTY_FUNCTION__))
;
881 }
882
883 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
884 const CompoundLiteralExpr *CL,
885 const MemRegion* superRegion);
886
887public:
888 QualType getValueType() const override { return CL->getType(); }
889
890 bool isBoundable() const override { return !CL->isFileScope(); }
891
892 void Profile(llvm::FoldingSetNodeID& ID) const override;
893
894 void dumpToStream(raw_ostream &os) const override;
895
896 const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
897
898 static bool classof(const MemRegion* R) {
899 return R->getKind() == CompoundLiteralRegionKind;
900 }
901};
902
903class DeclRegion : public TypedValueRegion {
904protected:
905 const ValueDecl *D;
906
907 DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
908 : TypedValueRegion(sReg, k), D(d) {
909 assert(classof(this))((classof(this)) ? static_cast<void> (0) : __assert_fail
("classof(this)", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 909, __PRETTY_FUNCTION__))
;
910 assert(d)((d) ? static_cast<void> (0) : __assert_fail ("d", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 910, __PRETTY_FUNCTION__))
;
911 }
912
913 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
914 const MemRegion* superRegion, Kind k);
915
916public:
917 const ValueDecl *getDecl() const { return D; }
918 void Profile(llvm::FoldingSetNodeID& ID) const override;
919
920 static bool classof(const MemRegion* R) {
921 unsigned k = R->getKind();
922 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
923 }
924};
925
926class VarRegion : public DeclRegion {
927 friend class MemRegionManager;
928
929 // Constructors and private methods.
930 VarRegion(const VarDecl *vd, const MemRegion *sReg)
931 : DeclRegion(vd, sReg, VarRegionKind) {
932 // VarRegion appears in unknown space when it's a block variable as seen
933 // from a block using it, when this block is analyzed at top-level.
934 // Other block variables appear within block data regions,
935 // which, unlike everything else on this list, are not memory spaces.
936 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||((isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion
>(sReg) || isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 937, __PRETTY_FUNCTION__))
937 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg))((isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion
>(sReg) || isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 937, __PRETTY_FUNCTION__))
;
938 }
939
940 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
941 const MemRegion *superRegion) {
942 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
943 }
944
945public:
946 void Profile(llvm::FoldingSetNodeID& ID) const override;
947
948 const VarDecl *getDecl() const { return cast<VarDecl>(D); }
949
950 const StackFrameContext *getStackFrame() const;
951
952 QualType getValueType() const override {
953 // FIXME: We can cache this if needed.
954 return getDecl()->getType();
955 }
956
957 void dumpToStream(raw_ostream &os) const override;
958
959 bool canPrintPrettyAsExpr() const override;
960
961 void printPrettyAsExpr(raw_ostream &os) const override;
962
963 static bool classof(const MemRegion* R) {
964 return R->getKind() == VarRegionKind;
965 }
966};
967
968/// CXXThisRegion - Represents the region for the implicit 'this' parameter
969/// in a call to a C++ method. This region doesn't represent the object
970/// referred to by 'this', but rather 'this' itself.
971class CXXThisRegion : public TypedValueRegion {
972 friend class MemRegionManager;
973
974 CXXThisRegion(const PointerType *thisPointerTy,
975 const StackArgumentsSpaceRegion *sReg)
976 : TypedValueRegion(sReg, CXXThisRegionKind),
977 ThisPointerTy(thisPointerTy) {
978 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&((ThisPointerTy->getPointeeType()->getAsCXXRecordDecl()
&& "Invalid region type!") ? static_cast<void>
(0) : __assert_fail ("ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && \"Invalid region type!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 979, __PRETTY_FUNCTION__))
979 "Invalid region type!")((ThisPointerTy->getPointeeType()->getAsCXXRecordDecl()
&& "Invalid region type!") ? static_cast<void>
(0) : __assert_fail ("ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && \"Invalid region type!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 979, __PRETTY_FUNCTION__))
;
980 }
981
982 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
983 const PointerType *PT,
984 const MemRegion *sReg);
985
986public:
987 void Profile(llvm::FoldingSetNodeID &ID) const override;
988
989 QualType getValueType() const override {
990 return QualType(ThisPointerTy, 0);
991 }
992
993 void dumpToStream(raw_ostream &os) const override;
994
995 static bool classof(const MemRegion* R) {
996 return R->getKind() == CXXThisRegionKind;
997 }
998
999private:
1000 const PointerType *ThisPointerTy;
1001};
1002
1003class FieldRegion : public DeclRegion {
1004 friend class MemRegionManager;
1005
1006 FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
1007 : DeclRegion(fd, sReg, FieldRegionKind) {}
1008
1009 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
1010 const MemRegion* superRegion) {
1011 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
1012 }
1013
1014public:
1015 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
1016
1017 QualType getValueType() const override {
1018 // FIXME: We can cache this if needed.
1019 return getDecl()->getType();
1020 }
1021
1022 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
1023
1024 void dumpToStream(raw_ostream &os) const override;
1025
1026 bool canPrintPretty() const override;
1027 void printPretty(raw_ostream &os) const override;
1028 bool canPrintPrettyAsExpr() const override;
1029 void printPrettyAsExpr(raw_ostream &os) const override;
1030
1031 static bool classof(const MemRegion* R) {
1032 return R->getKind() == FieldRegionKind;
1033 }
1034};
1035
1036class ObjCIvarRegion : public DeclRegion {
1037 friend class MemRegionManager;
1038
1039 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1040
1041 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1042 const MemRegion* superRegion);
1043
1044public:
1045 const ObjCIvarDecl *getDecl() const;
1046 QualType getValueType() const override;
1047
1048 bool canPrintPrettyAsExpr() const override;
1049 void printPrettyAsExpr(raw_ostream &os) const override;
1050
1051 void dumpToStream(raw_ostream &os) const override;
1052
1053 static bool classof(const MemRegion* R) {
1054 return R->getKind() == ObjCIvarRegionKind;
1055 }
1056};
1057
1058//===----------------------------------------------------------------------===//
1059// Auxiliary data classes for use with MemRegions.
1060//===----------------------------------------------------------------------===//
1061
1062class RegionRawOffset {
1063 friend class ElementRegion;
1064
1065 const MemRegion *Region;
1066 CharUnits Offset;
1067
1068 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1069 : Region(reg), Offset(offset) {}
1070
1071public:
1072 // FIXME: Eventually support symbolic offsets.
1073 CharUnits getOffset() const { return Offset; }
1074 const MemRegion *getRegion() const { return Region; }
1075
1076 void dumpToStream(raw_ostream &os) const;
1077 void dump() const;
1078};
1079
1080/// ElementRegin is used to represent both array elements and casts.
1081class ElementRegion : public TypedValueRegion {
1082 friend class MemRegionManager;
1083
1084 QualType ElementType;
1085 NonLoc Index;
1086
1087 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1088 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1089 Index(Idx) {
1090 assert((!Idx.getAs<nonloc::ConcreteInt>() ||(((!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc
::ConcreteInt>().getValue().isSigned()) && "The index must be signed"
) ? static_cast<void> (0) : __assert_fail ("(!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && \"The index must be signed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1092, __PRETTY_FUNCTION__))
1091 Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&(((!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc
::ConcreteInt>().getValue().isSigned()) && "The index must be signed"
) ? static_cast<void> (0) : __assert_fail ("(!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && \"The index must be signed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1092, __PRETTY_FUNCTION__))
1092 "The index must be signed")(((!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc
::ConcreteInt>().getValue().isSigned()) && "The index must be signed"
) ? static_cast<void> (0) : __assert_fail ("(!Idx.getAs<nonloc::ConcreteInt>() || Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && \"The index must be signed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1092, __PRETTY_FUNCTION__))
;
1093 assert(!elementType.isNull() && !elementType->isVoidType() &&((!elementType.isNull() && !elementType->isVoidType
() && "Invalid region type!") ? static_cast<void>
(0) : __assert_fail ("!elementType.isNull() && !elementType->isVoidType() && \"Invalid region type!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1094, __PRETTY_FUNCTION__))
1094 "Invalid region type!")((!elementType.isNull() && !elementType->isVoidType
() && "Invalid region type!") ? static_cast<void>
(0) : __assert_fail ("!elementType.isNull() && !elementType->isVoidType() && \"Invalid region type!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1094, __PRETTY_FUNCTION__))
;
1095 }
1096
1097 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1098 SVal Idx, const MemRegion* superRegion);
1099
1100public:
1101 NonLoc getIndex() const { return Index; }
1102
1103 QualType getValueType() const override { return ElementType; }
1104
1105 QualType getElementType() const { return ElementType; }
1106
1107 /// Compute the offset within the array. The array might also be a subobject.
1108 RegionRawOffset getAsArrayOffset() const;
1109
1110 void dumpToStream(raw_ostream &os) const override;
1111
1112 void Profile(llvm::FoldingSetNodeID& ID) const override;
1113
1114 static bool classof(const MemRegion* R) {
1115 return R->getKind() == ElementRegionKind;
1116 }
1117};
1118
1119// C++ temporary object associated with an expression.
1120class CXXTempObjectRegion : public TypedValueRegion {
1121 friend class MemRegionManager;
1122
1123 Expr const *Ex;
1124
1125 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1126 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1127 assert(E)((E) ? static_cast<void> (0) : __assert_fail ("E", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1127, __PRETTY_FUNCTION__))
;
1128 assert(isa<StackLocalsSpaceRegion>(sReg) ||((isa<StackLocalsSpaceRegion>(sReg) || isa<GlobalInternalSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<StackLocalsSpaceRegion>(sReg) || isa<GlobalInternalSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1129, __PRETTY_FUNCTION__))
1129 isa<GlobalInternalSpaceRegion>(sReg))((isa<StackLocalsSpaceRegion>(sReg) || isa<GlobalInternalSpaceRegion
>(sReg)) ? static_cast<void> (0) : __assert_fail ("isa<StackLocalsSpaceRegion>(sReg) || isa<GlobalInternalSpaceRegion>(sReg)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1129, __PRETTY_FUNCTION__))
;
1130 }
1131
1132 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1133 Expr const *E, const MemRegion *sReg);
1134
1135public:
1136 const Expr *getExpr() const { return Ex; }
1137
1138 QualType getValueType() const override { return Ex->getType(); }
1139
1140 void dumpToStream(raw_ostream &os) const override;
1141
1142 void Profile(llvm::FoldingSetNodeID &ID) const override;
1143
1144 static bool classof(const MemRegion* R) {
1145 return R->getKind() == CXXTempObjectRegionKind;
1146 }
1147};
1148
1149// CXXBaseObjectRegion represents a base object within a C++ object. It is
1150// identified by the base class declaration and the region of its parent object.
1151class CXXBaseObjectRegion : public TypedValueRegion {
1152 friend class MemRegionManager;
1153
1154 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1155
1156 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1157 const SubRegion *SReg)
1158 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1159 assert(RD)((RD) ? static_cast<void> (0) : __assert_fail ("RD", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1159, __PRETTY_FUNCTION__))
;
1160 }
1161
1162 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1163 bool IsVirtual, const MemRegion *SReg);
1164
1165public:
1166 const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1167 bool isVirtual() const { return Data.getInt(); }
1168
1169 QualType getValueType() const override;
1170
1171 void dumpToStream(raw_ostream &os) const override;
1172
1173 void Profile(llvm::FoldingSetNodeID &ID) const override;
1174
1175 bool canPrintPrettyAsExpr() const override;
1176
1177 void printPrettyAsExpr(raw_ostream &os) const override;
1178
1179 static bool classof(const MemRegion *region) {
1180 return region->getKind() == CXXBaseObjectRegionKind;
1181 }
1182};
1183
1184// CXXDerivedObjectRegion represents a derived-class object that surrounds
1185// a C++ object. It is identified by the derived class declaration and the
1186// region of its parent object. It is a bit counter-intuitive (but not otherwise
1187// unseen) that this region represents a larger segment of memory that its
1188// super-region.
1189class CXXDerivedObjectRegion : public TypedValueRegion {
1190 friend class MemRegionManager;
1191
1192 const CXXRecordDecl *DerivedD;
1193
1194 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1195 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1196 assert(DerivedD)((DerivedD) ? static_cast<void> (0) : __assert_fail ("DerivedD"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1196, __PRETTY_FUNCTION__))
;
1197 // In case of a concrete region, it should always be possible to model
1198 // the base-to-derived cast by undoing a previous derived-to-base cast,
1199 // otherwise the cast is most likely ill-formed.
1200 assert(SReg->getSymbolicBase() &&((SReg->getSymbolicBase() && "Should have unwrapped a base region instead!"
) ? static_cast<void> (0) : __assert_fail ("SReg->getSymbolicBase() && \"Should have unwrapped a base region instead!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1201, __PRETTY_FUNCTION__))
1201 "Should have unwrapped a base region instead!")((SReg->getSymbolicBase() && "Should have unwrapped a base region instead!"
) ? static_cast<void> (0) : __assert_fail ("SReg->getSymbolicBase() && \"Should have unwrapped a base region instead!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
, 1201, __PRETTY_FUNCTION__))
;
1202 }
1203
1204 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1205 const MemRegion *SReg);
1206
1207public:
1208 const CXXRecordDecl *getDecl() const { return DerivedD; }
1209
1210 QualType getValueType() const override;
1211
1212 void dumpToStream(raw_ostream &os) const override;
1213
1214 void Profile(llvm::FoldingSetNodeID &ID) const override;
1215
1216 bool canPrintPrettyAsExpr() const override;
1217
1218 void printPrettyAsExpr(raw_ostream &os) const override;
1219
1220 static bool classof(const MemRegion *region) {
1221 return region->getKind() == CXXDerivedObjectRegionKind;
1222 }
1223};
1224
1225template<typename RegionTy>
1226const RegionTy* MemRegion::getAs() const {
1227 if (const auto *RT = dyn_cast<RegionTy>(this))
1228 return RT;
1229
1230 return nullptr;
1231}
1232
1233//===----------------------------------------------------------------------===//
1234// MemRegionManager - Factory object for creating regions.
1235//===----------------------------------------------------------------------===//
1236
1237class MemRegionManager {
1238 ASTContext &C;
1239 llvm::BumpPtrAllocator& A;
1240 llvm::FoldingSet<MemRegion> Regions;
1241
1242 GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1243 GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1244 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1245
1246 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1247 StackLocalsSpaceRegions;
1248 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1249 StackArgumentsSpaceRegions;
1250 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1251 StaticsGlobalSpaceRegions;
1252
1253 HeapSpaceRegion *heap = nullptr;
1254 UnknownSpaceRegion *unknown = nullptr;
1255 CodeSpaceRegion *code = nullptr;
1256
1257public:
1258 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
1259 ~MemRegionManager();
1260
1261 ASTContext &getContext() { return C; }
1262
1263 llvm::BumpPtrAllocator &getAllocator() { return A; }
1264
1265 /// getStackLocalsRegion - Retrieve the memory region associated with the
1266 /// specified stack frame.
1267 const StackLocalsSpaceRegion *
1268 getStackLocalsRegion(const StackFrameContext *STC);
1269
1270 /// getStackArgumentsRegion - Retrieve the memory region associated with
1271 /// function/method arguments of the specified stack frame.
1272 const StackArgumentsSpaceRegion *
1273 getStackArgumentsRegion(const StackFrameContext *STC);
1274
1275 /// getGlobalsRegion - Retrieve the memory region associated with
1276 /// global variables.
1277 const GlobalsSpaceRegion *getGlobalsRegion(
1278 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1279 const CodeTextRegion *R = nullptr);
1280
1281 /// getHeapRegion - Retrieve the memory region associated with the
1282 /// generic "heap".
1283 const HeapSpaceRegion *getHeapRegion();
1284
1285 /// getUnknownRegion - Retrieve the memory region associated with unknown
1286 /// memory space.
1287 const UnknownSpaceRegion *getUnknownRegion();
1288
1289 const CodeSpaceRegion *getCodeRegion();
1290
1291 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1292 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1293 const LocationContext *LC);
1294
1295 /// getCompoundLiteralRegion - Retrieve the region associated with a
1296 /// given CompoundLiteral.
1297 const CompoundLiteralRegion*
1298 getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1299 const LocationContext *LC);
1300
1301 /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1302 /// parameter 'this'.
1303 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1304 const LocationContext *LC);
1305
1306 /// Retrieve or create a "symbolic" memory region.
1307 const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1308
1309 /// Return a unique symbolic region belonging to heap memory space.
1310 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1311
1312 const StringRegion *getStringRegion(const StringLiteral *Str);
1313
1314 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1315
1316 /// getVarRegion - Retrieve or create the memory region associated with
1317 /// a specified VarDecl and LocationContext.
1318 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1319
1320 /// getVarRegion - Retrieve or create the memory region associated with
1321 /// a specified VarDecl and super region.
1322 const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
1323
1324 /// getElementRegion - Retrieve the memory region associated with the
1325 /// associated element type, index, and super region.
1326 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1327 const SubRegion *superRegion,
1328 ASTContext &Ctx);
1329
1330 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1331 const SubRegion *superRegion) {
1332 return getElementRegion(ER->getElementType(), ER->getIndex(),
1333 superRegion, ER->getContext());
1334 }
1335
1336 /// getFieldRegion - Retrieve or create the memory region associated with
1337 /// a specified FieldDecl. 'superRegion' corresponds to the containing
1338 /// memory region (which typically represents the memory representing
1339 /// a structure or class).
1340 const FieldRegion *getFieldRegion(const FieldDecl *fd,
1341 const SubRegion* superRegion);
1342
1343 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1344 const SubRegion *superRegion) {
1345 return getFieldRegion(FR->getDecl(), superRegion);
1346 }
1347
1348 /// getObjCIvarRegion - Retrieve or create the memory region associated with
1349 /// a specified Objective-c instance variable. 'superRegion' corresponds
1350 /// to the containing region (which typically represents the Objective-C
1351 /// object).
1352 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1353 const SubRegion* superRegion);
1354
1355 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1356 LocationContext const *LC);
1357
1358 /// Create a CXXBaseObjectRegion with the given base class for region
1359 /// \p Super.
1360 ///
1361 /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1362 const CXXBaseObjectRegion *
1363 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1364 bool IsVirtual);
1365
1366 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1367 /// super region.
1368 const CXXBaseObjectRegion *
1369 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1370 const SubRegion *superRegion) {
1371 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1372 baseReg->isVirtual());
1373 }
1374
1375 /// Create a CXXDerivedObjectRegion with the given derived class for region
1376 /// \p Super. This should not be used for casting an existing
1377 /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1378 /// should be removed.
1379 const CXXDerivedObjectRegion *
1380 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1381 const SubRegion *Super);
1382
1383 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1384 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1385 CanQualType locTy,
1386 AnalysisDeclContext *AC);
1387
1388 /// getBlockDataRegion - Get the memory region associated with an instance
1389 /// of a block. Unlike many other MemRegions, the LocationContext*
1390 /// argument is allowed to be NULL for cases where we have no known
1391 /// context.
1392 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1393 const LocationContext *lc,
1394 unsigned blockCount);
1395
1396 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1397 /// by static references. This differs from getCXXTempObjectRegion in the
1398 /// super-region used.
1399 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1400
1401private:
1402 template <typename RegionTy, typename SuperTy,
1403 typename Arg1Ty>
1404 RegionTy* getSubRegion(const Arg1Ty arg1,
1405 const SuperTy* superRegion);
1406
1407 template <typename RegionTy, typename SuperTy,
1408 typename Arg1Ty, typename Arg2Ty>
1409 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1410 const SuperTy* superRegion);
1411
1412 template <typename RegionTy, typename SuperTy,
1413 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1414 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1415 const Arg3Ty arg3,
1416 const SuperTy* superRegion);
1417
1418 template <typename REG>
1419 const REG* LazyAllocate(REG*& region);
1420
1421 template <typename REG, typename ARG>
1422 const REG* LazyAllocate(REG*& region, ARG a);
1423};
1424
1425//===----------------------------------------------------------------------===//
1426// Out-of-line member definitions.
1427//===----------------------------------------------------------------------===//
1428
1429inline ASTContext &MemRegion::getContext() const {
1430 return getMemRegionManager()->getContext();
1431}
1432
1433//===----------------------------------------------------------------------===//
1434// Means for storing region/symbol handling traits.
1435//===----------------------------------------------------------------------===//
1436
1437/// Information about invalidation for a particular region/symbol.
1438class RegionAndSymbolInvalidationTraits {
1439 using StorageTypeForKinds = unsigned char;
1440
1441 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1442 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1443
1444 using const_region_iterator =
1445 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1446 using const_symbol_iterator =
1447 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1448
1449public:
1450 /// Describes different invalidation traits.
1451 enum InvalidationKinds {
1452 /// Tells that a region's contents is not changed.
1453 TK_PreserveContents = 0x1,
1454
1455 /// Suppress pointer-escaping of a region.
1456 TK_SuppressEscape = 0x2,
1457
1458 // Do not invalidate super region.
1459 TK_DoNotInvalidateSuperRegion = 0x4,
1460
1461 /// When applied to a MemSpaceRegion, indicates the entire memory space
1462 /// should be invalidated.
1463 TK_EntireMemSpace = 0x8
1464
1465 // Do not forget to extend StorageTypeForKinds if number of traits exceed
1466 // the number of bits StorageTypeForKinds can store.
1467 };
1468
1469 void setTrait(SymbolRef Sym, InvalidationKinds IK);
1470 void setTrait(const MemRegion *MR, InvalidationKinds IK);
1471 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1472 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1473};
1474
1475//===----------------------------------------------------------------------===//
1476// Pretty-printing regions.
1477//===----------------------------------------------------------------------===//
1478inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1479 R->dumpToStream(os);
1480 return os;
1481}
1482
1483} // namespace ento
1484
1485} // namespace clang
1486
1487#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H