Bug Summary

File:tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Warning:line 1452, 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 -analyzer-config-compatibility-mode=true -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-9/lib/clang/9.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/lib/StaticAnalyzer/Core -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/StaticAnalyzer/Core -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/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/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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-9~svn362543/build-llvm/tools/clang/lib/StaticAnalyzer/Core -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -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-2019-06-05-060531-1271-1 -x c++ /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp -faddrsig

/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp

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

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

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