Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Warning:line 951, column 36
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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