clang 20.0.0git
MemRegion.cpp
Go to the documentation of this file.
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
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"
25#include "clang/AST/Type.h"
29#include "clang/Basic/LLVM.h"
36#include "llvm/ADT/APInt.h"
37#include "llvm/ADT/FoldingSet.h"
38#include "llvm/ADT/PointerUnion.h"
39#include "llvm/ADT/SmallString.h"
40#include "llvm/ADT/StringRef.h"
41#include "llvm/ADT/Twine.h"
42#include "llvm/ADT/iterator_range.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 <optional>
55#include <string>
56#include <tuple>
57#include <utility>
58
59using namespace clang;
60using namespace ento;
61
62#define DEBUG_TYPE "MemRegion"
63
64//===----------------------------------------------------------------------===//
65// MemRegion Construction.
66//===----------------------------------------------------------------------===//
67
68template <typename RegionTy, typename SuperTy, typename Arg1Ty>
69RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
70 const SuperTy *superRegion) {
71 llvm::FoldingSetNodeID ID;
72 RegionTy::ProfileRegion(ID, arg1, superRegion);
73 void *InsertPos;
74 auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
75
76 if (!R) {
77 R = new (A) 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 = new (A) RegionTy(arg1, arg2, superRegion);
94 Regions.InsertNode(R, InsertPos);
95 }
96
97 return R;
98}
99
100template <typename RegionTy, typename SuperTy,
101 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
102RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
103 const Arg3Ty arg3,
104 const SuperTy *superRegion) {
105 llvm::FoldingSetNodeID ID;
106 RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
107 void *InsertPos;
108 auto *R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
109
110 if (!R) {
111 R = new (A) 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.
127
128//===----------------------------------------------------------------------===//
129// Basic methods.
130//===----------------------------------------------------------------------===//
131
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
146 const SubRegion* r = this;
147 do {
149 if (const auto *sr = dyn_cast<SubRegion>(superRegion)) {
150 r = sr;
151 continue;
152 }
154 } while (true);
155}
156
158 const auto *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
159 return SSR ? SSR->getStackFrame() : nullptr;
160}
161
162const StackFrameContext *
164 const auto *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
165 return SSR ? SSR->getStackFrame() : nullptr;
166}
167
169 assert(isa<StackSpaceRegion>(getMemorySpace()) &&
170 "A temporary object can only be allocated on the stack");
171 return cast<StackSpaceRegion>(getMemorySpace())->getStackFrame();
172}
173
174ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
175 : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {
176 assert(IVD);
177}
178
179const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { return IVD; }
180
182 return getDecl()->getType();
183}
184
186 return QualType(getDecl()->getTypeForDecl(), 0);
187}
188
190 return QualType(getDecl()->getTypeForDecl(), 0);
191}
192
194 assert(getDecl() &&
195 "`ParamVarRegion` support functions without `Decl` not implemented"
196 " yet.");
197 return getDecl()->getType();
198}
199
201 const Decl *D = getStackFrame()->getDecl();
202
203 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
204 assert(Index < FD->param_size());
205 return FD->parameters()[Index];
206 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
207 assert(Index < BD->param_size());
208 return BD->parameters()[Index];
209 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
210 assert(Index < MD->param_size());
211 return MD->parameters()[Index];
212 } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
213 assert(Index < CD->param_size());
214 return CD->parameters()[Index];
215 } else {
216 llvm_unreachable("Unexpected Decl kind!");
217 }
218}
219
220//===----------------------------------------------------------------------===//
221// FoldingSet profiling.
222//===----------------------------------------------------------------------===//
223
224void MemSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
225 ID.AddInteger(static_cast<unsigned>(getKind()));
226}
227
228void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
229 ID.AddInteger(static_cast<unsigned>(getKind()));
230 ID.AddPointer(getStackFrame());
231}
232
233void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
234 ID.AddInteger(static_cast<unsigned>(getKind()));
235 ID.AddPointer(getCodeRegion());
236}
237
238void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
239 const StringLiteral *Str,
240 const MemRegion *superRegion) {
241 ID.AddInteger(static_cast<unsigned>(StringRegionKind));
242 ID.AddPointer(Str);
243 ID.AddPointer(superRegion);
244}
245
246void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
247 const ObjCStringLiteral *Str,
248 const MemRegion *superRegion) {
249 ID.AddInteger(static_cast<unsigned>(ObjCStringRegionKind));
250 ID.AddPointer(Str);
251 ID.AddPointer(superRegion);
252}
253
254void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
255 const Expr *Ex, unsigned cnt,
256 const MemRegion *superRegion) {
257 ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
258 ID.AddPointer(Ex);
259 ID.AddInteger(cnt);
260 ID.AddPointer(superRegion);
261}
262
263void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
264 ProfileRegion(ID, Ex, Cnt, superRegion);
265}
266
267void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
268 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
269}
270
271void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
272 const CompoundLiteralExpr *CL,
273 const MemRegion* superRegion) {
274 ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
275 ID.AddPointer(CL);
276 ID.AddPointer(superRegion);
277}
278
279void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
280 const PointerType *PT,
281 const MemRegion *sRegion) {
282 ID.AddInteger(static_cast<unsigned>(CXXThisRegionKind));
283 ID.AddPointer(PT);
284 ID.AddPointer(sRegion);
285}
286
287void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
288 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
289}
290
291void FieldRegion::Profile(llvm::FoldingSetNodeID &ID) const {
292 ProfileRegion(ID, getDecl(), superRegion);
293}
294
295void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
296 const ObjCIvarDecl *ivd,
297 const MemRegion* superRegion) {
298 ID.AddInteger(static_cast<unsigned>(ObjCIvarRegionKind));
299 ID.AddPointer(ivd);
300 ID.AddPointer(superRegion);
301}
302
303void ObjCIvarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
304 ProfileRegion(ID, getDecl(), superRegion);
305}
306
307void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
308 const VarDecl *VD,
309 const MemRegion *superRegion) {
310 ID.AddInteger(static_cast<unsigned>(NonParamVarRegionKind));
311 ID.AddPointer(VD);
312 ID.AddPointer(superRegion);
313}
314
315void NonParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
316 ProfileRegion(ID, getDecl(), superRegion);
317}
318
319void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
320 unsigned Idx, const MemRegion *SReg) {
321 ID.AddInteger(static_cast<unsigned>(ParamVarRegionKind));
322 ID.AddPointer(OE);
323 ID.AddInteger(Idx);
324 ID.AddPointer(SReg);
325}
326
327void ParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
328 ProfileRegion(ID, getOriginExpr(), getIndex(), superRegion);
329}
330
331void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
332 const MemRegion *sreg) {
333 ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
334 ID.Add(sym);
335 ID.AddPointer(sreg);
336}
337
338void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
340}
341
342void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
343 QualType ElementType, SVal Idx,
344 const MemRegion* superRegion) {
345 ID.AddInteger(MemRegion::ElementRegionKind);
346 ID.Add(ElementType);
347 ID.AddPointer(superRegion);
348 Idx.Profile(ID);
349}
350
351void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
352 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
353}
354
355void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
356 const NamedDecl *FD,
357 const MemRegion*) {
358 ID.AddInteger(MemRegion::FunctionCodeRegionKind);
359 ID.AddPointer(FD);
360}
361
362void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
363 FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
364}
365
366void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
367 const BlockDecl *BD, CanQualType,
368 const AnalysisDeclContext *AC,
369 const MemRegion*) {
370 ID.AddInteger(MemRegion::BlockCodeRegionKind);
371 ID.AddPointer(BD);
372}
373
374void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
375 BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
376}
377
378void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
379 const BlockCodeRegion *BC,
380 const LocationContext *LC,
381 unsigned BlkCount,
382 const MemRegion *sReg) {
383 ID.AddInteger(MemRegion::BlockDataRegionKind);
384 ID.AddPointer(BC);
385 ID.AddPointer(LC);
386 ID.AddInteger(BlkCount);
387 ID.AddPointer(sReg);
388}
389
390void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
391 BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
392}
393
394void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
395 Expr const *Ex,
396 const MemRegion *sReg) {
397 ID.AddPointer(Ex);
398 ID.AddPointer(sReg);
399}
400
401void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
402 ProfileRegion(ID, Ex, getSuperRegion());
403}
404
405void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
406 const Expr *E,
407 const ValueDecl *D,
408 const MemRegion *sReg) {
409 ID.AddPointer(E);
410 ID.AddPointer(D);
411 ID.AddPointer(sReg);
412}
413
415 llvm::FoldingSetNodeID &ID) const {
416 ProfileRegion(ID, Ex, ExD, getSuperRegion());
417}
418
419void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
420 const CXXRecordDecl *RD,
421 bool IsVirtual,
422 const MemRegion *SReg) {
423 ID.AddPointer(RD);
424 ID.AddBoolean(IsVirtual);
425 ID.AddPointer(SReg);
426}
427
428void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
429 ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
430}
431
432void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
433 const CXXRecordDecl *RD,
434 const MemRegion *SReg) {
435 ID.AddPointer(RD);
436 ID.AddPointer(SReg);
437}
438
439void CXXDerivedObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
440 ProfileRegion(ID, getDecl(), superRegion);
441}
442
443//===----------------------------------------------------------------------===//
444// Region anchors.
445//===----------------------------------------------------------------------===//
446
447void GlobalsSpaceRegion::anchor() {}
448
449void NonStaticGlobalSpaceRegion::anchor() {}
450
451void StackSpaceRegion::anchor() {}
452
453void TypedRegion::anchor() {}
454
455void TypedValueRegion::anchor() {}
456
457void CodeTextRegion::anchor() {}
458
459void SubRegion::anchor() {}
460
461//===----------------------------------------------------------------------===//
462// Region pretty-printing.
463//===----------------------------------------------------------------------===//
464
465LLVM_DUMP_METHOD void MemRegion::dump() const {
466 dumpToStream(llvm::errs());
467}
468
469std::string MemRegion::getString() const {
470 std::string s;
471 llvm::raw_string_ostream os(s);
472 dumpToStream(os);
473 return s;
474}
475
476void MemRegion::dumpToStream(raw_ostream &os) const {
477 os << "<Unknown Region>";
478}
479
480void AllocaRegion::dumpToStream(raw_ostream &os) const {
481 os << "alloca{S" << Ex->getID(getContext()) << ',' << Cnt << '}';
482}
483
484void FunctionCodeRegion::dumpToStream(raw_ostream &os) const {
485 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
486}
487
488void BlockCodeRegion::dumpToStream(raw_ostream &os) const {
489 os << "block_code{" << static_cast<const void *>(this) << '}';
490}
491
492void BlockDataRegion::dumpToStream(raw_ostream &os) const {
493 os << "block_data{" << BC;
494 os << "; ";
495 for (auto Var : referenced_vars())
496 os << "(" << Var.getCapturedRegion() << "<-" << Var.getOriginalRegion()
497 << ") ";
498 os << '}';
499}
500
501void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
502 // FIXME: More elaborate pretty-printing.
503 os << "{ S" << CL->getID(getContext()) << " }";
504}
505
506void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
507 os << "temp_object{" << getValueType() << ", "
508 << "S" << Ex->getID(getContext()) << '}';
509}
510
512 os << "lifetime_extended_object{" << getValueType() << ", ";
513 if (const IdentifierInfo *ID = ExD->getIdentifier())
514 os << ID->getName();
515 else
516 os << "D" << ExD->getID();
517 os << ", "
518 << "S" << Ex->getID(getContext()) << '}';
519}
520
521void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
522 os << "Base{" << superRegion << ',' << getDecl()->getName() << '}';
523}
524
525void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {
526 os << "Derived{" << superRegion << ',' << getDecl()->getName() << '}';
527}
528
529void CXXThisRegion::dumpToStream(raw_ostream &os) const {
530 os << "this";
531}
532
533void ElementRegion::dumpToStream(raw_ostream &os) const {
534 os << "Element{" << superRegion << ',' << Index << ',' << getElementType()
535 << '}';
536}
537
538void FieldRegion::dumpToStream(raw_ostream &os) const {
539 os << superRegion << "." << *getDecl();
540}
541
542void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
543 os << "Ivar{" << superRegion << ',' << *getDecl() << '}';
544}
545
546void StringRegion::dumpToStream(raw_ostream &os) const {
547 assert(Str != nullptr && "Expecting non-null StringLiteral");
548 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
549}
550
551void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
552 assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
553 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
554}
555
556void SymbolicRegion::dumpToStream(raw_ostream &os) const {
557 if (isa<HeapSpaceRegion>(getSuperRegion()))
558 os << "Heap";
559 os << "SymRegion{" << sym << '}';
560}
561
562void NonParamVarRegion::dumpToStream(raw_ostream &os) const {
563 if (const IdentifierInfo *ID = VD->getIdentifier())
564 os << ID->getName();
565 else
566 os << "NonParamVarRegion{D" << VD->getID() << '}';
567}
568
569LLVM_DUMP_METHOD void RegionRawOffset::dump() const {
570 dumpToStream(llvm::errs());
571}
572
573void RegionRawOffset::dumpToStream(raw_ostream &os) const {
574 os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
575}
576
577void CodeSpaceRegion::dumpToStream(raw_ostream &os) const {
578 os << "CodeSpaceRegion";
579}
580
581void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
582 os << "StaticGlobalsMemSpace{" << CR << '}';
583}
584
585void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
586 os << "GlobalInternalSpaceRegion";
587}
588
589void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
590 os << "GlobalSystemSpaceRegion";
591}
592
593void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
594 os << "GlobalImmutableSpaceRegion";
595}
596
597void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
598 os << "HeapSpaceRegion";
599}
600
601void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
602 os << "UnknownSpaceRegion";
603}
604
605void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
606 os << "StackArgumentsSpaceRegion";
607}
608
609void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
610 os << "StackLocalsSpaceRegion";
611}
612
613void ParamVarRegion::dumpToStream(raw_ostream &os) const {
614 const ParmVarDecl *PVD = getDecl();
615 assert(PVD &&
616 "`ParamVarRegion` support functions without `Decl` not implemented"
617 " yet.");
618 if (const IdentifierInfo *ID = PVD->getIdentifier()) {
619 os << ID->getName();
620 } else {
621 os << "ParamVarRegion{P" << PVD->getID() << '}';
622 }
623}
624
626 return canPrintPrettyAsExpr();
627}
628
630 return false;
631}
632
633StringRef MemRegion::getKindStr() const {
634 switch (getKind()) {
635#define REGION(Id, Parent) \
636 case Id##Kind: \
637 return #Id;
638#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
639#undef REGION
640 }
641 llvm_unreachable("Unkown kind!");
642}
643
644void MemRegion::printPretty(raw_ostream &os) const {
645 assert(canPrintPretty() && "This region cannot be printed pretty.");
646 os << "'";
648 os << "'";
649}
650
651void MemRegion::printPrettyAsExpr(raw_ostream &) const {
652 llvm_unreachable("This region cannot be printed pretty.");
653}
654
655bool NonParamVarRegion::canPrintPrettyAsExpr() const { return true; }
656
657void NonParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
658 os << getDecl()->getName();
659}
660
661bool ParamVarRegion::canPrintPrettyAsExpr() const { return true; }
662
663void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
664 assert(getDecl() &&
665 "`ParamVarRegion` support functions without `Decl` not implemented"
666 " yet.");
667 os << getDecl()->getName();
668}
669
671 return true;
672}
673
674void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
675 os << getDecl()->getName();
676}
677
679 return true;
680}
681
684}
685
686void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
687 assert(canPrintPrettyAsExpr());
689 os << "." << getDecl()->getName();
690}
691
692void FieldRegion::printPretty(raw_ostream &os) const {
693 if (canPrintPrettyAsExpr()) {
694 os << "\'";
696 os << "'";
697 } else {
698 os << "field " << "\'" << getDecl()->getName() << "'";
699 }
700}
701
704}
705
706void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
708}
709
712}
713
714void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
716}
717
718std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
719 std::string VariableName;
720 std::string ArrayIndices;
721 const MemRegion *R = this;
722 SmallString<50> buf;
723 llvm::raw_svector_ostream os(buf);
724
725 // Obtain array indices to add them to the variable name.
726 const ElementRegion *ER = nullptr;
727 while ((ER = R->getAs<ElementRegion>())) {
728 // Index is a ConcreteInt.
729 if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
731 CI->getValue().toString(Idx);
732 ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
733 }
734 // Index is symbolic, but may have a descriptive name.
735 else {
736 auto SI = ER->getIndex().getAs<nonloc::SymbolVal>();
737 if (!SI)
738 return "";
739
740 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
741 if (!OR)
742 return "";
743
744 std::string Idx = OR->getDescriptiveName(false);
745 if (Idx.empty())
746 return "";
747
748 ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
749 }
750 R = ER->getSuperRegion();
751 }
752
753 // Get variable name.
754 if (R && R->canPrintPrettyAsExpr()) {
755 R->printPrettyAsExpr(os);
756 if (UseQuotes)
757 return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
758 else
759 return (llvm::Twine(os.str()) + ArrayIndices).str();
760 }
761
762 return VariableName;
763}
764
766 // Check for more specific regions first.
767 if (auto *FR = dyn_cast<FieldRegion>(this)) {
768 return FR->getDecl()->getSourceRange();
769 }
770
771 if (auto *VR = dyn_cast<VarRegion>(this->getBaseRegion())) {
772 return VR->getDecl()->getSourceRange();
773 }
774
775 // Return invalid source range (can be checked by client).
776 return {};
777}
778
779//===----------------------------------------------------------------------===//
780// MemRegionManager methods.
781//===----------------------------------------------------------------------===//
782
784 SValBuilder &SVB) const {
785 const auto *SR = cast<SubRegion>(MR);
786 SymbolManager &SymMgr = SVB.getSymbolManager();
787
788 switch (SR->getKind()) {
789 case MemRegion::AllocaRegionKind:
790 case MemRegion::SymbolicRegionKind:
791 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
792 case MemRegion::StringRegionKind:
793 return SVB.makeIntVal(
794 cast<StringRegion>(SR)->getStringLiteral()->getByteLength() + 1,
795 SVB.getArrayIndexType());
796 case MemRegion::CompoundLiteralRegionKind:
797 case MemRegion::CXXBaseObjectRegionKind:
798 case MemRegion::CXXDerivedObjectRegionKind:
799 case MemRegion::CXXTempObjectRegionKind:
800 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
801 case MemRegion::CXXThisRegionKind:
802 case MemRegion::ObjCIvarRegionKind:
803 case MemRegion::NonParamVarRegionKind:
804 case MemRegion::ParamVarRegionKind:
805 case MemRegion::ElementRegionKind:
806 case MemRegion::ObjCStringRegionKind: {
807 QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
808 if (isa<VariableArrayType>(Ty))
809 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
810
811 if (Ty->isIncompleteType())
812 return UnknownVal();
813
814 return getElementExtent(Ty, SVB);
815 }
816 case MemRegion::FieldRegionKind: {
817 // Force callers to deal with bitfields explicitly.
818 if (cast<FieldRegion>(SR)->getDecl()->isBitField())
819 return UnknownVal();
820
821 QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
822 const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
823
824 // We currently don't model flexible array members (FAMs), which are:
825 // - int array[]; of IncompleteArrayType
826 // - int array[0]; of ConstantArrayType with size 0
827 // - int array[1]; of ConstantArrayType with size 1
828 // https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
829 const auto isFlexibleArrayMemberCandidate =
830 [this](const ArrayType *AT) -> bool {
831 if (!AT)
832 return false;
833
834 auto IsIncompleteArray = [](const ArrayType *AT) {
835 return isa<IncompleteArrayType>(AT);
836 };
837 auto IsArrayOfZero = [](const ArrayType *AT) {
838 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
839 return CAT && CAT->isZeroSize();
840 };
841 auto IsArrayOfOne = [](const ArrayType *AT) {
842 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
843 return CAT && CAT->getSize() == 1;
844 };
845
847 const FAMKind StrictFlexArraysLevel =
848 Ctx.getLangOpts().getStrictFlexArraysLevel();
849
850 // "Default": Any trailing array member is a FAM.
851 // Since we cannot tell at this point if this array is a trailing member
852 // or not, let's just do the same as for "OneZeroOrIncomplete".
853 if (StrictFlexArraysLevel == FAMKind::Default)
854 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
855
856 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
857 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
858
859 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
860 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
861
862 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
863 return IsIncompleteArray(AT);
864 };
865
866 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
867 return UnknownVal();
868
869 return Size;
870 }
871 // FIXME: The following are being used in 'SimpleSValBuilder' and in
872 // 'ArrayBoundChecker::checkLocation' because there is no symbol to
873 // represent the regions more appropriately.
874 case MemRegion::BlockDataRegionKind:
875 case MemRegion::BlockCodeRegionKind:
876 case MemRegion::FunctionCodeRegionKind:
877 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
878 default:
879 llvm_unreachable("Unhandled region");
880 }
881}
882
883template <typename REG>
884const REG *MemRegionManager::LazyAllocate(REG*& region) {
885 if (!region) {
886 region = new (A) REG(*this);
887 }
888
889 return region;
890}
891
892template <typename REG, typename ARG>
893const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
894 if (!region) {
895 region = new (A) REG(this, a);
896 }
897
898 return region;
899}
900
903 assert(STC);
904 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
905
906 if (R)
907 return R;
908
909 R = new (A) StackLocalsSpaceRegion(*this, STC);
910 return R;
911}
912
915 assert(STC);
916 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
917
918 if (R)
919 return R;
920
921 R = new (A) StackArgumentsSpaceRegion(*this, STC);
922 return R;
923}
924
927 const CodeTextRegion *CR) {
928 if (!CR) {
929 if (K == MemRegion::GlobalSystemSpaceRegionKind)
930 return LazyAllocate(SystemGlobals);
931 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
932 return LazyAllocate(ImmutableGlobals);
933 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
934 return LazyAllocate(InternalGlobals);
935 }
936
937 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
938 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
939 if (R)
940 return R;
941
942 R = new (A) StaticGlobalSpaceRegion(*this, CR);
943 return R;
944}
945
947 return LazyAllocate(heap);
948}
949
951 return LazyAllocate(unknown);
952}
953
955 return LazyAllocate(code);
956}
957
958//===----------------------------------------------------------------------===//
959// Constructing regions.
960//===----------------------------------------------------------------------===//
961
963 return getSubRegion<StringRegion>(
964 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
965}
966
967const ObjCStringRegion *
969 return getSubRegion<ObjCStringRegion>(
970 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
971}
972
973/// Look through a chain of LocationContexts to either find the
974/// StackFrameContext that matches a DeclContext, or find a VarRegion
975/// for a variable captured by a block.
976static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
978 const DeclContext *DC,
979 const VarDecl *VD) {
980 while (LC) {
981 if (const auto *SFC = dyn_cast<StackFrameContext>(LC)) {
982 if (cast<DeclContext>(SFC->getDecl()) == DC)
983 return SFC;
984 }
985 if (const auto *BC = dyn_cast<BlockInvocationContext>(LC)) {
986 const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
987 // FIXME: This can be made more efficient.
988 for (auto Var : BR->referenced_vars()) {
989 const TypedValueRegion *OrigR = Var.getOriginalRegion();
990 if (const auto *VR = dyn_cast<VarRegion>(OrigR)) {
991 if (VR->getDecl() == VD)
992 return cast<VarRegion>(Var.getCapturedRegion());
993 }
994 }
995 }
996
997 LC = LC->getParent();
998 }
999 return (const StackFrameContext *)nullptr;
1000}
1001
1003 const LocationContext *LC) {
1004 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1005 if (PVD) {
1006 unsigned Index = PVD->getFunctionScopeIndex();
1007 const StackFrameContext *SFC = LC->getStackFrame();
1008 const Stmt *CallSite = SFC->getCallSite();
1009 if (CallSite) {
1010 const Decl *D = SFC->getDecl();
1011 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1012 if (Index < FD->param_size() && FD->parameters()[Index] == PVD)
1013 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1015 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
1016 if (Index < BD->param_size() && BD->parameters()[Index] == PVD)
1017 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1019 } else {
1020 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1022 }
1023 }
1024 }
1025
1026 D = D->getCanonicalDecl();
1027 const MemRegion *sReg = nullptr;
1028
1029 if (D->hasGlobalStorage() && !D->isStaticLocal()) {
1030 QualType Ty = D->getType();
1031 assert(!Ty.isNull());
1032 if (Ty.isConstQualified()) {
1033 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1034 } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
1035 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
1036 } else {
1037 sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
1038 }
1039
1040 // Finally handle static locals.
1041 } else {
1042 // FIXME: Once we implement scope handling, we will need to properly lookup
1043 // 'D' to the proper LocationContext.
1044 const DeclContext *DC = D->getDeclContext();
1045 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
1047
1048 if (V.is<const VarRegion*>())
1049 return V.get<const VarRegion*>();
1050
1051 const auto *STC = V.get<const StackFrameContext *>();
1052
1053 if (!STC) {
1054 // FIXME: Assign a more sensible memory space to static locals
1055 // we see from within blocks that we analyze as top-level declarations.
1056 sReg = getUnknownRegion();
1057 } else {
1058 if (D->hasLocalStorage()) {
1059 sReg =
1060 isa<ParmVarDecl, ImplicitParamDecl>(D)
1061 ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
1062 : static_cast<const MemRegion *>(getStackLocalsRegion(STC));
1063 }
1064 else {
1065 assert(D->isStaticLocal());
1066 const Decl *STCD = STC->getDecl();
1067 if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
1068 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1069 getFunctionCodeRegion(cast<NamedDecl>(STCD)));
1070 else if (const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1071 // FIXME: The fallback type here is totally bogus -- though it should
1072 // never be queried, it will prevent uniquing with the real
1073 // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
1074 // signature.
1075 QualType T;
1076 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
1077 T = TSI->getType();
1078 if (T.isNull())
1079 T = getContext().VoidTy;
1080 if (!T->getAs<FunctionType>()) {
1082 T = getContext().getFunctionType(T, std::nullopt, Ext);
1083 }
1085
1086 const BlockCodeRegion *BTR =
1088 STC->getAnalysisDeclContext());
1089 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1090 BTR);
1091 }
1092 else {
1093 sReg = getGlobalsRegion();
1094 }
1095 }
1096 }
1097 }
1098
1099 return getNonParamVarRegion(D, sReg);
1100}
1101
1102const NonParamVarRegion *
1104 const MemRegion *superR) {
1105 // Prefer the definition over the canonical decl as the canonical form.
1106 D = D->getCanonicalDecl();
1107 if (const VarDecl *Def = D->getDefinition())
1108 D = Def;
1109 return getSubRegion<NonParamVarRegion>(D, superR);
1110}
1111
1112const ParamVarRegion *
1113MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
1114 const LocationContext *LC) {
1115 const StackFrameContext *SFC = LC->getStackFrame();
1116 assert(SFC);
1117 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1119}
1120
1121const BlockDataRegion *
1123 const LocationContext *LC,
1124 unsigned blockCount) {
1125 const MemSpaceRegion *sReg = nullptr;
1126 const BlockDecl *BD = BC->getDecl();
1127 if (!BD->hasCaptures()) {
1128 // This handles 'static' blocks.
1129 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1130 }
1131 else {
1132 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1133
1134 // ARC managed blocks can be initialized on stack or directly in heap
1135 // depending on the implementations. So we initialize them with
1136 // UnknownRegion.
1137 if (!IsArcManagedBlock && LC) {
1138 // FIXME: Once we implement scope handling, we want the parent region
1139 // to be the scope.
1140 const StackFrameContext *STC = LC->getStackFrame();
1141 assert(STC);
1142 sReg = getStackLocalsRegion(STC);
1143 } else {
1144 // We allow 'LC' to be NULL for cases where want BlockDataRegions
1145 // without context-sensitivity.
1146 sReg = getUnknownRegion();
1147 }
1148 }
1149
1150 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
1151}
1152
1155 const LocationContext *LC) {
1156 const MemSpaceRegion *sReg = nullptr;
1157
1158 if (CL->isFileScope())
1159 sReg = getGlobalsRegion();
1160 else {
1161 const StackFrameContext *STC = LC->getStackFrame();
1162 assert(STC);
1163 sReg = getStackLocalsRegion(STC);
1164 }
1165
1166 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
1167}
1168
1169const ElementRegion *
1171 const SubRegion *superRegion,
1172 const ASTContext &Ctx) {
1173 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
1174
1175 llvm::FoldingSetNodeID ID;
1176 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
1177
1178 void *InsertPos;
1179 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1180 auto *R = cast_or_null<ElementRegion>(data);
1181
1182 if (!R) {
1183 R = new (A) ElementRegion(T, Idx, superRegion);
1184 Regions.InsertNode(R, InsertPos);
1185 }
1186
1187 return R;
1188}
1189
1190const FunctionCodeRegion *
1192 // To think: should we canonicalize the declaration here?
1193 return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
1194}
1195
1196const BlockCodeRegion *
1198 AnalysisDeclContext *AC) {
1199 return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion());
1200}
1201
1202const SymbolicRegion *
1204 const MemSpaceRegion *MemSpace) {
1205 if (MemSpace == nullptr)
1206 MemSpace = getUnknownRegion();
1207 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1208}
1209
1211 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
1212}
1213
1214const FieldRegion*
1216 const SubRegion* superRegion){
1217 return getSubRegion<FieldRegion>(d, superRegion);
1218}
1219
1220const ObjCIvarRegion*
1222 const SubRegion* superRegion) {
1223 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1224}
1225
1228 LocationContext const *LC) {
1229 const StackFrameContext *SFC = LC->getStackFrame();
1230 assert(SFC);
1231 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
1232}
1233
1236 const Expr *Ex, const ValueDecl *VD, const LocationContext *LC) {
1237 const StackFrameContext *SFC = LC->getStackFrame();
1238 assert(SFC);
1239 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1240 Ex, VD, getStackLocalsRegion(SFC));
1241}
1242
1245 const Expr *Ex, const ValueDecl *VD) {
1246 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1247 Ex, VD,
1248 getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
1249}
1250
1251/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
1252/// class of the type of \p Super.
1253static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
1254 const TypedValueRegion *Super,
1255 bool IsVirtual) {
1256 BaseClass = BaseClass->getCanonicalDecl();
1257
1259 if (!Class)
1260 return true;
1261
1262 if (IsVirtual)
1263 return Class->isVirtuallyDerivedFrom(BaseClass);
1264
1265 for (const auto &I : Class->bases()) {
1266 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1267 return true;
1268 }
1269
1270 return false;
1271}
1272
1273const CXXBaseObjectRegion *
1275 const SubRegion *Super,
1276 bool IsVirtual) {
1277 if (isa<TypedValueRegion>(Super)) {
1278 assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual));
1279 (void)&isValidBaseClass;
1280
1281 if (IsVirtual) {
1282 // Virtual base regions should not be layered, since the layout rules
1283 // are different.
1284 while (const auto *Base = dyn_cast<CXXBaseObjectRegion>(Super))
1285 Super = cast<SubRegion>(Base->getSuperRegion());
1286 assert(Super && !isa<MemSpaceRegion>(Super));
1287 }
1288 }
1289
1290 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1291}
1292
1295 const SubRegion *Super) {
1296 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1297}
1298
1299const CXXThisRegion*
1301 const LocationContext *LC) {
1302 const auto *PT = thisPointerTy->getAs<PointerType>();
1303 assert(PT);
1304 // Inside the body of the operator() of a lambda a this expr might refer to an
1305 // object in one of the parent location contexts.
1306 const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1307 // FIXME: when operator() of lambda is analyzed as a top level function and
1308 // 'this' refers to a this to the enclosing scope, there is no right region to
1309 // return.
1310 while (!LC->inTopFrame() && (!D || D->isStatic() ||
1311 PT != D->getThisType()->getAs<PointerType>())) {
1312 LC = LC->getParent();
1313 D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1314 }
1315 const StackFrameContext *STC = LC->getStackFrame();
1316 assert(STC);
1317 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
1318}
1319
1320const AllocaRegion*
1322 const LocationContext *LC) {
1323 const StackFrameContext *STC = LC->getStackFrame();
1324 assert(STC);
1325 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
1326}
1327
1329 const MemRegion *R = this;
1330 const auto *SR = dyn_cast<SubRegion>(this);
1331
1332 while (SR) {
1333 R = SR->getSuperRegion();
1334 SR = dyn_cast<SubRegion>(R);
1335 }
1336
1337 return cast<MemSpaceRegion>(R);
1338}
1339
1341 return isa<StackSpaceRegion>(getMemorySpace());
1342}
1343
1345 return isa<StackLocalsSpaceRegion>(getMemorySpace());
1346}
1347
1349 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
1350}
1351
1352// Strips away all elements and fields.
1353// Returns the base region of them.
1355 const MemRegion *R = this;
1356 while (true) {
1357 switch (R->getKind()) {
1358 case MemRegion::ElementRegionKind:
1359 case MemRegion::FieldRegionKind:
1360 case MemRegion::ObjCIvarRegionKind:
1361 case MemRegion::CXXBaseObjectRegionKind:
1362 case MemRegion::CXXDerivedObjectRegionKind:
1363 R = cast<SubRegion>(R)->getSuperRegion();
1364 continue;
1365 default:
1366 break;
1367 }
1368 break;
1369 }
1370 return R;
1371}
1372
1373// Returns the region of the root class of a C++ class hierarchy.
1375 const MemRegion *R = this;
1376 while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1377 R = BR->getSuperRegion();
1378 return R;
1379}
1380
1382 return false;
1383}
1384
1385//===----------------------------------------------------------------------===//
1386// View handling.
1387//===----------------------------------------------------------------------===//
1388
1389const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {
1390 const MemRegion *R = this;
1391 while (true) {
1392 switch (R->getKind()) {
1393 case ElementRegionKind: {
1394 const auto *ER = cast<ElementRegion>(R);
1395 if (!ER->getIndex().isZeroConstant())
1396 return R;
1397 R = ER->getSuperRegion();
1398 break;
1399 }
1400 case CXXBaseObjectRegionKind:
1401 case CXXDerivedObjectRegionKind:
1402 if (!StripBaseAndDerivedCasts)
1403 return R;
1404 R = cast<TypedValueRegion>(R)->getSuperRegion();
1405 break;
1406 default:
1407 return R;
1408 }
1409 }
1410}
1411
1413 const auto *SubR = dyn_cast<SubRegion>(this);
1414
1415 while (SubR) {
1416 if (const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1417 return SymR;
1418 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1419 }
1420 return nullptr;
1421}
1422
1424 int64_t offset = 0;
1425 const ElementRegion *ER = this;
1426 const MemRegion *superR = nullptr;
1427 ASTContext &C = getContext();
1428
1429 // FIXME: Handle multi-dimensional arrays.
1430
1431 while (ER) {
1432 superR = ER->getSuperRegion();
1433
1434 // FIXME: generalize to symbolic offsets.
1435 SVal index = ER->getIndex();
1436 if (auto CI = index.getAs<nonloc::ConcreteInt>()) {
1437 // Update the offset.
1438 int64_t i = CI->getValue().getSExtValue();
1439
1440 if (i != 0) {
1441 QualType elemType = ER->getElementType();
1442
1443 // If we are pointing to an incomplete type, go no further.
1444 if (elemType->isIncompleteType()) {
1445 superR = ER;
1446 break;
1447 }
1448
1449 int64_t size = C.getTypeSizeInChars(elemType).getQuantity();
1450 if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1451 offset = *NewOffset;
1452 } else {
1453 LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: "
1454 << "offset overflowing, returning unknown\n");
1455
1456 return nullptr;
1457 }
1458 }
1459
1460 // Go to the next ElementRegion (if any).
1461 ER = dyn_cast<ElementRegion>(superR);
1462 continue;
1463 }
1464
1465 return nullptr;
1466 }
1467
1468 assert(superR && "super region cannot be NULL");
1469 return RegionRawOffset(superR, CharUnits::fromQuantity(offset));
1470}
1471
1472/// Returns true if \p Base is an immediate base class of \p Child
1473static bool isImmediateBase(const CXXRecordDecl *Child,
1474 const CXXRecordDecl *Base) {
1475 assert(Child && "Child must not be null");
1476 // Note that we do NOT canonicalize the base class here, because
1477 // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1478 // so be it; at least we won't crash.
1479 for (const auto &I : Child->bases()) {
1480 if (I.getType()->getAsCXXRecordDecl() == Base)
1481 return true;
1482 }
1483
1484 return false;
1485}
1486
1488 const MemRegion *SymbolicOffsetBase = nullptr;
1489 int64_t Offset = 0;
1490
1491 while (true) {
1492 switch (R->getKind()) {
1493 case MemRegion::CodeSpaceRegionKind:
1494 case MemRegion::StackLocalsSpaceRegionKind:
1495 case MemRegion::StackArgumentsSpaceRegionKind:
1496 case MemRegion::HeapSpaceRegionKind:
1497 case MemRegion::UnknownSpaceRegionKind:
1498 case MemRegion::StaticGlobalSpaceRegionKind:
1499 case MemRegion::GlobalInternalSpaceRegionKind:
1500 case MemRegion::GlobalSystemSpaceRegionKind:
1501 case MemRegion::GlobalImmutableSpaceRegionKind:
1502 // Stores can bind directly to a region space to set a default value.
1503 assert(Offset == 0 && !SymbolicOffsetBase);
1504 goto Finish;
1505
1506 case MemRegion::FunctionCodeRegionKind:
1507 case MemRegion::BlockCodeRegionKind:
1508 case MemRegion::BlockDataRegionKind:
1509 // These will never have bindings, but may end up having values requested
1510 // if the user does some strange casting.
1511 if (Offset != 0)
1512 SymbolicOffsetBase = R;
1513 goto Finish;
1514
1515 case MemRegion::SymbolicRegionKind:
1516 case MemRegion::AllocaRegionKind:
1517 case MemRegion::CompoundLiteralRegionKind:
1518 case MemRegion::CXXThisRegionKind:
1519 case MemRegion::StringRegionKind:
1520 case MemRegion::ObjCStringRegionKind:
1521 case MemRegion::NonParamVarRegionKind:
1522 case MemRegion::ParamVarRegionKind:
1523 case MemRegion::CXXTempObjectRegionKind:
1524 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1525 // Usual base regions.
1526 goto Finish;
1527
1528 case MemRegion::ObjCIvarRegionKind:
1529 // This is a little strange, but it's a compromise between
1530 // ObjCIvarRegions having unknown compile-time offsets (when using the
1531 // non-fragile runtime) and yet still being distinct, non-overlapping
1532 // regions. Thus we treat them as "like" base regions for the purposes
1533 // of computing offsets.
1534 goto Finish;
1535
1536 case MemRegion::CXXBaseObjectRegionKind: {
1537 const auto *BOR = cast<CXXBaseObjectRegion>(R);
1538 R = BOR->getSuperRegion();
1539
1540 QualType Ty;
1541 bool RootIsSymbolic = false;
1542 if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1543 Ty = TVR->getDesugaredValueType(R->getContext());
1544 } else if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1545 // If our base region is symbolic, we don't know what type it really is.
1546 // Pretend the type of the symbol is the true dynamic type.
1547 // (This will at least be self-consistent for the life of the symbol.)
1548 Ty = SR->getPointeeStaticType();
1549 RootIsSymbolic = true;
1550 }
1551
1552 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1553 if (!Child) {
1554 // We cannot compute the offset of the base class.
1555 SymbolicOffsetBase = R;
1556 } else {
1557 if (RootIsSymbolic) {
1558 // Base layers on symbolic regions may not be type-correct.
1559 // Double-check the inheritance here, and revert to a symbolic offset
1560 // if it's invalid (e.g. due to a reinterpret_cast).
1561 if (BOR->isVirtual()) {
1562 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1563 SymbolicOffsetBase = R;
1564 } else {
1565 if (!isImmediateBase(Child, BOR->getDecl()))
1566 SymbolicOffsetBase = R;
1567 }
1568 }
1569 }
1570
1571 // Don't bother calculating precise offsets if we already have a
1572 // symbolic offset somewhere in the chain.
1573 if (SymbolicOffsetBase)
1574 continue;
1575
1576 CharUnits BaseOffset;
1577 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1578 if (BOR->isVirtual())
1579 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1580 else
1581 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1582
1583 // The base offset is in chars, not in bits.
1584 Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
1585 break;
1586 }
1587
1588 case MemRegion::CXXDerivedObjectRegionKind: {
1589 // TODO: Store the base type in the CXXDerivedObjectRegion and use it.
1590 goto Finish;
1591 }
1592
1593 case MemRegion::ElementRegionKind: {
1594 const auto *ER = cast<ElementRegion>(R);
1595 R = ER->getSuperRegion();
1596
1597 QualType EleTy = ER->getValueType();
1598 if (EleTy->isIncompleteType()) {
1599 // We cannot compute the offset of the base class.
1600 SymbolicOffsetBase = R;
1601 continue;
1602 }
1603
1604 SVal Index = ER->getIndex();
1605 if (std::optional<nonloc::ConcreteInt> CI =
1606 Index.getAs<nonloc::ConcreteInt>()) {
1607 // Don't bother calculating precise offsets if we already have a
1608 // symbolic offset somewhere in the chain.
1609 if (SymbolicOffsetBase)
1610 continue;
1611
1612 int64_t i = CI->getValue().getSExtValue();
1613 // This type size is in bits.
1614 Offset += i * R->getContext().getTypeSize(EleTy);
1615 } else {
1616 // We cannot compute offset for non-concrete index.
1617 SymbolicOffsetBase = R;
1618 }
1619 break;
1620 }
1621 case MemRegion::FieldRegionKind: {
1622 const auto *FR = cast<FieldRegion>(R);
1623 R = FR->getSuperRegion();
1624 assert(R);
1625
1626 const RecordDecl *RD = FR->getDecl()->getParent();
1627 if (RD->isUnion() || !RD->isCompleteDefinition()) {
1628 // We cannot compute offset for incomplete type.
1629 // For unions, we could treat everything as offset 0, but we'd rather
1630 // treat each field as a symbolic offset so they aren't stored on top
1631 // of each other, since we depend on things in typed regions actually
1632 // matching their types.
1633 SymbolicOffsetBase = R;
1634 }
1635
1636 // Don't bother calculating precise offsets if we already have a
1637 // symbolic offset somewhere in the chain.
1638 if (SymbolicOffsetBase)
1639 continue;
1640
1641 // Get the field number.
1642 unsigned idx = 0;
1644 FE = RD->field_end(); FI != FE; ++FI, ++idx) {
1645 if (FR->getDecl() == *FI)
1646 break;
1647 }
1648 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1649 // This is offset in bits.
1650 Offset += Layout.getFieldOffset(idx);
1651 break;
1652 }
1653 }
1654 }
1655
1656 Finish:
1657 if (SymbolicOffsetBase)
1658 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1659 return RegionOffset(R, Offset);
1660}
1661
1663 if (!cachedOffset)
1664 cachedOffset = calculateOffset(this);
1665 return *cachedOffset;
1666}
1667
1668//===----------------------------------------------------------------------===//
1669// BlockDataRegion
1670//===----------------------------------------------------------------------===//
1671
1672std::pair<const VarRegion *, const VarRegion *>
1673BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1675 const VarRegion *VR = nullptr;
1676 const VarRegion *OriginalVR = nullptr;
1677
1678 if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1679 VR = MemMgr.getNonParamVarRegion(VD, this);
1680 OriginalVR = MemMgr.getVarRegion(VD, LC);
1681 }
1682 else {
1683 if (LC) {
1684 VR = MemMgr.getVarRegion(VD, LC);
1685 OriginalVR = VR;
1686 }
1687 else {
1688 VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion());
1689 OriginalVR = MemMgr.getVarRegion(VD, LC);
1690 }
1691 }
1692 return std::make_pair(VR, OriginalVR);
1693}
1694
1695void BlockDataRegion::LazyInitializeReferencedVars() {
1696 if (ReferencedVars)
1697 return;
1698
1700 const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
1701 auto NumBlockVars =
1702 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1703
1704 if (NumBlockVars == 0) {
1705 ReferencedVars = (void*) 0x1;
1706 return;
1707 }
1708
1710 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1711 BumpVectorContext BC(A);
1712
1713 using VarVec = BumpVector<const MemRegion *>;
1714
1715 auto *BV = new (A) VarVec(BC, NumBlockVars);
1716 auto *BVOriginal = new (A) VarVec(BC, NumBlockVars);
1717
1718 for (const auto *VD : ReferencedBlockVars) {
1719 const VarRegion *VR = nullptr;
1720 const VarRegion *OriginalVR = nullptr;
1721 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1722 assert(VR);
1723 assert(OriginalVR);
1724 BV->push_back(VR, BC);
1725 BVOriginal->push_back(OriginalVR, BC);
1726 }
1727
1728 ReferencedVars = BV;
1729 OriginalVars = BVOriginal;
1730}
1731
1734 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1735
1736 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
1737
1738 if (Vec == (void*) 0x1)
1739 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1740
1741 auto *VecOriginal =
1742 static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
1743
1745 VecOriginal->begin());
1746}
1747
1750 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1751
1752 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
1753
1754 if (Vec == (void*) 0x1)
1755 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1756
1757 auto *VecOriginal =
1758 static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
1759
1761 VecOriginal->end());
1762}
1763
1764llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1766 return llvm::make_range(referenced_vars_begin(), referenced_vars_end());
1767}
1768
1770 for (const auto &I : referenced_vars()) {
1771 if (I.getCapturedRegion() == R)
1772 return I.getOriginalRegion();
1773 }
1774 return nullptr;
1775}
1776
1777//===----------------------------------------------------------------------===//
1778// RegionAndSymbolInvalidationTraits
1779//===----------------------------------------------------------------------===//
1780
1782 InvalidationKinds IK) {
1783 SymTraitsMap[Sym] |= IK;
1784}
1785
1787 InvalidationKinds IK) {
1788 assert(MR);
1789 if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
1790 setTrait(SR->getSymbol(), IK);
1791 else
1792 MRTraitsMap[MR] |= IK;
1793}
1794
1796 InvalidationKinds IK) const {
1797 const_symbol_iterator I = SymTraitsMap.find(Sym);
1798 if (I != SymTraitsMap.end())
1799 return I->second & IK;
1800
1801 return false;
1802}
1803
1805 InvalidationKinds IK) const {
1806 if (!MR)
1807 return false;
1808
1809 if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
1810 return hasTrait(SR->getSymbol(), IK);
1811
1812 const_region_iterator I = MRTraitsMap.find(MR);
1813 if (I != MRTraitsMap.end())
1814 return I->second & IK;
1815
1816 return false;
1817}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3341
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static llvm::PointerUnion< const StackFrameContext *, const VarRegion * > getStackOrCaptureRegionForDeclContext(const LocationContext *LC, const DeclContext *DC, const VarDecl *VD)
Look through a chain of LocationContexts to either find the StackFrameContext that matches a DeclCont...
Definition: MemRegion.cpp:977
static bool isImmediateBase(const CXXRecordDecl *Child, const CXXRecordDecl *Base)
Returns true if Base is an immediate base class of Child.
Definition: MemRegion.cpp:1473
static bool isValidBaseClass(const CXXRecordDecl *BaseClass, const TypedValueRegion *Super, bool IsVirtual)
Checks whether BaseClass is a valid virtual or direct non-virtual base class of the type of Super.
Definition: MemRegion.cpp:1253
static RegionOffset calculateOffset(const MemRegion *R)
Definition: MemRegion.cpp:1487
Defines the SourceManager interface.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
SourceManager & getSourceManager()
Definition: ASTContext.h:721
QualType getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2628
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2394
CanQualType VoidTy
Definition: ASTContext.h:1119
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1615
uint64_t getCharWidth() const
Return the size of the character type, in bits.
Definition: ASTContext.h:2398
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Definition: RecordLayout.h:200
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:249
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:259
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3571
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4471
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:4590
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:4557
TypeSourceInfo * getSignatureAsWritten() const
Definition: Decl.h:4554
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:524
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3428
bool isFileScope() const
Definition: Expr.h:3455
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2370
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
int64_t getID() const
Definition: DeclBase.cpp:1174
SourceLocation getLocation() const
Definition: DeclBase.h:446
DeclContext * getDeclContext()
Definition: DeclBase.h:455
bool hasAttr() const
Definition: DeclBase.h:584
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
std::string getAsString() const
Retrieve the human-readable string for this name.
This represents one expression.
Definition: Expr.h:110
Represents a member of a struct/union/class.
Definition: Decl.h:3030
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4313
One of these records is kept for each identifier that is lexed.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const LocationContext * getParent() const
It might return null.
const StackFrameContext * getStackFrame() const
virtual bool inTopFrame() const
This represents a decl that may have a name.
Definition: Decl.h:249
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1951
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
Represents a parameter to a function.
Definition: Decl.h:1722
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3192
A (possibly-)qualified type.
Definition: Type.h:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:7828
Represents a struct/union/class.
Definition: Decl.h:4145
field_iterator field_end() const
Definition: Decl.h:4354
field_iterator field_begin() const
Definition: Decl.cpp:5068
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
It represents a stack frame of the call stack (based on CallEvent).
const Stmt * getCallSite() const
Stmt - This represents one statement.
Definition: Stmt.h:84
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
int64_t getID(const ASTContext &Context) const
Definition: Stmt.cpp:362
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1778
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3664
bool isUnion() const
Definition: Decl.h:3767
A container of type source information.
Definition: Type.h:7726
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1882
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2362
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8545
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
QualType getType() const
Definition: Decl.h:678
Represents a variable declaration or definition.
Definition: Decl.h:879
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1132
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
Definition: MemRegion.h:478
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:480
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:263
BlockCodeRegion - A region that represents code texts of blocks (closures).
Definition: MemRegion.h:631
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
Definition: MemRegion.h:661
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:488
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl * getDecl() const
Definition: MemRegion.h:656
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:374
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:678
const VarRegion * getOriginalRegion(const VarRegion *VR) const
Return the original region for a captured region, if one exists.
Definition: MemRegion.cpp:1769
referenced_vars_iterator referenced_vars_begin() const
Definition: MemRegion.cpp:1733
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockCodeRegion * getCodeRegion() const
Definition: MemRegion.h:705
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:390
referenced_vars_iterator referenced_vars_end() const
Definition: MemRegion.cpp:1749
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:492
llvm::iterator_range< referenced_vars_iterator > referenced_vars() const
Definition: MemRegion.cpp:1765
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:706
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1327
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:702
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:428
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:521
QualType getValueType() const override
Definition: MemRegion.cpp:185
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:714
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:439
QualType getValueType() const override
Definition: MemRegion.cpp:189
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:525
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:710
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1370
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:414
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:511
const StackFrameContext * getStackFrame() const
It might return null.
Definition: MemRegion.cpp:163
QualType getValueType() const override
Definition: MemRegion.h:1298
QualType getValueType() const override
Definition: MemRegion.h:1259
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:401
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:506
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrameContext * getStackFrame() const
Definition: MemRegion.cpp:168
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method.
Definition: MemRegion.h:1074
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:287
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:529
CodeSpaceRegion - The memory space that holds the executable code of functions and blocks.
Definition: MemRegion.h:231
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:577
CompoundLiteralRegion - A memory region representing a compound literal.
Definition: MemRegion.h:900
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:267
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:501
ElementRegion is used to represent both array elements and casts.
Definition: MemRegion.h:1199
QualType getElementType() const
Definition: MemRegion.h:1223
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:351
NonLoc getIndex() const
Definition: MemRegion.h:1219
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
Definition: MemRegion.cpp:1423
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:533
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:686
bool canPrintPretty() const override
Returns true if this region can be printed in a user-friendly way.
Definition: MemRegion.cpp:678
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:682
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:538
void printPretty(raw_ostream &os) const override
Print the region for use in diagnostics.
Definition: MemRegion.cpp:692
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:291
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
Definition: MemRegion.h:1125
FunctionCodeRegion - A region that represents code texts of function.
Definition: MemRegion.h:584
const NamedDecl * getDecl() const
Definition: MemRegion.h:612
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:484
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:362
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:593
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:585
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:589
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:597
const HeapSpaceRegion * getHeapRegion()
getHeapRegion - Retrieve the memory region associated with the generic "heap".
Definition: MemRegion.cpp:946
const StackArgumentsSpaceRegion * getStackArgumentsRegion(const StackFrameContext *STC)
getStackArgumentsRegion - Retrieve the memory region associated with function/method arguments of the...
Definition: MemRegion.cpp:914
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.
Definition: MemRegion.cpp:1300
llvm::BumpPtrAllocator & getAllocator()
Definition: MemRegion.h:1432
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
Definition: MemRegion.cpp:1197
const UnknownSpaceRegion * getUnknownRegion()
getUnknownRegion - Retrieve the memory region associated with unknown memory space.
Definition: MemRegion.cpp:950
const CXXDerivedObjectRegion * getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super)
Create a CXXDerivedObjectRegion with the given derived class for region Super.
Definition: MemRegion.cpp:1294
const CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC)
getCompoundLiteralRegion - Retrieve the region associated with a given CompoundLiteral.
Definition: MemRegion.cpp:1154
const FieldRegion * getFieldRegion(const FieldDecl *fd, const SubRegion *superRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
Definition: MemRegion.cpp:1215
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC)
getAllocaRegion - Retrieve a region associated with a call to alloca().
Definition: MemRegion.cpp:1321
const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)
getElementRegion - Retrieve the memory region associated with the associated element type,...
Definition: MemRegion.cpp:1170
const VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Definition: MemRegion.cpp:1002
const NonParamVarRegion * getNonParamVarRegion(const VarDecl *VD, const MemRegion *superR)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Definition: MemRegion.cpp:1103
const StackLocalsSpaceRegion * getStackLocalsRegion(const StackFrameContext *STC)
getStackLocalsRegion - Retrieve the memory region associated with the specified stack frame.
Definition: MemRegion.cpp:902
const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)
getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...
Definition: MemRegion.cpp:1221
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
Definition: MemRegion.cpp:1210
const ObjCStringRegion * getObjCStringRegion(const ObjCStringLiteral *Str)
Definition: MemRegion.cpp:968
const StringRegion * getStringRegion(const StringLiteral *Str)
Definition: MemRegion.cpp:962
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
Definition: MemRegion.cpp:783
const ParamVarRegion * getParamVarRegion(const Expr *OriginExpr, unsigned Index, const LocationContext *LC)
getParamVarRegion - Retrieve or create the memory region associated with a specified CallExpr,...
Definition: MemRegion.cpp:1113
const CodeSpaceRegion * getCodeRegion()
Definition: MemRegion.cpp:954
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
Definition: MemRegion.cpp:1235
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
Definition: MemRegion.cpp:1227
const GlobalsSpaceRegion * getGlobalsRegion(MemRegion::Kind K=MemRegion::GlobalInternalSpaceRegionKind, const CodeTextRegion *R=nullptr)
getGlobalsRegion - Retrieve the memory region associated with global variables.
Definition: MemRegion.cpp:926
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
Definition: MemRegion.cpp:1203
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
Definition: MemRegion.cpp:1191
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
Definition: MemRegion.cpp:1122
const CXXBaseObjectRegion * getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual)
Create a CXXBaseObjectRegion with the given base class for region Super.
Definition: MemRegion.cpp:1274
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
Definition: MemRegion.cpp:1244
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:97
virtual bool canPrintPrettyAsExpr() const
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:629
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
Definition: MemRegion.cpp:1328
bool hasStackParametersStorage() const
Definition: MemRegion.cpp:1348
StringRef getKindStr() const
Definition: MemRegion.cpp:633
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
Definition: MemRegion.cpp:1662
bool hasStackStorage() const
Definition: MemRegion.cpp:1340
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1389
ASTContext & getContext() const
Definition: MemRegion.h:1620
std::string getDescriptiveName(bool UseQuotes=true) const
Get descriptive name for memory region.
Definition: MemRegion.cpp:718
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:1381
virtual void dumpToStream(raw_ostream &os) const
Definition: MemRegion.cpp:476
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
Definition: MemRegion.cpp:1412
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1354
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
Definition: MemRegion.cpp:644
virtual void printPrettyAsExpr(raw_ostream &os) const
Print the region as expression.
Definition: MemRegion.cpp:651
bool hasStackNonParametersStorage() const
Definition: MemRegion.cpp:1344
std::string getString() const
Get a string representation of a region for debug use.
Definition: MemRegion.cpp:469
const RegionTy * getAs() const
Definition: MemRegion.h:1388
Kind getKind() const
Definition: MemRegion.h:175
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getMostDerivedObjectRegion() const
Recursively retrieve the region of the most derived class instance of regions of C++ base class insta...
Definition: MemRegion.cpp:1374
virtual MemRegionManager & getMemRegionManager() const =0
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
Definition: MemRegion.cpp:625
SourceRange sourceRange() const
Retrieve source range from memory region.
Definition: MemRegion.cpp:765
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
Definition: MemRegion.h:208
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:224
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:655
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:315
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:657
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:562
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const override
Definition: MemRegion.h:1006
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:670
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:303
QualType getValueType() const override
Definition: MemRegion.cpp:181
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:674
LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl * getDecl() const override
Definition: MemRegion.cpp:179
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:542
The region associated with an ObjCStringLiteral.
Definition: MemRegion.h:863
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:551
ParamVarRegion - Represents a region for paremters.
Definition: MemRegion.h:1034
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:661
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getOriginExpr() const
Definition: MemRegion.h:1051
const ParmVarDecl * getDecl() const override
TODO: What does this return?
Definition: MemRegion.cpp:200
unsigned getIndex() const
Definition: MemRegion.h:1052
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:327
QualType getValueType() const override
Definition: MemRegion.cpp:193
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:613
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:663
InvalidationKinds
Describes different invalidation traits.
Definition: MemRegion.h:1642
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1795
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Definition: MemRegion.cpp:1781
Represent a region's offset within the top level base region.
Definition: MemRegion.h:64
static const int64_t Symbolic
Definition: MemRegion.h:74
CharUnits getOffset() const
Definition: MemRegion.h:1189
void dumpToStream(raw_ostream &os) const
Definition: MemRegion.cpp:573
const MemRegion * getRegion() const
Definition: MemRegion.h:1192
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
Definition: SValBuilder.h:290
QualType getArrayIndexType() const
Definition: SValBuilder.h:157
SymbolManager & getSymbolManager()
Definition: SValBuilder.h:164
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:55
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: SVals.h:94
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
Definition: SVals.h:86
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:605
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:609
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrameContext * getStackFrame() const
Definition: MemRegion.h:405
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:228
The region of the static variables within the current CodeTextRegion scope.
Definition: MemRegion.h:265
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:233
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:581
LLVM_ATTRIBUTE_RETURNS_NONNULL const CodeTextRegion * getCodeRegion() const
Definition: MemRegion.h:281
StringRegion - Region associated with a StringLiteral.
Definition: MemRegion.h:829
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:546
SubRegion - A region that subsets another larger region.
Definition: MemRegion.h:446
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
Definition: MemRegion.h:459
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:132
const MemRegion * superRegion
Definition: MemRegion.h:450
MemRegionManager & getMemRegionManager() const override
Definition: MemRegion.cpp:145
Symbolic value.
Definition: SymExpr.h:30
const SymbolExtent * getExtentSymbol(const SubRegion *R)
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:780
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:556
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:338
static void ProfileRegion(llvm::FoldingSetNodeID &ID, SymbolRef sym, const MemRegion *superRegion)
Definition: MemRegion.cpp:331
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:535
virtual QualType getValueType() const =0
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:601
const VarDecl * getDecl() const override=0
const StackFrameContext * getStackFrame() const
It might return null.
Definition: MemRegion.cpp:157
Value representing integer constant.
Definition: SVals.h:297
Represents symbolic expression that isn't a location.
Definition: SVals.h:276
DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Extra information about a function prototype.
Definition: Type.h:5092
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57