clang 19.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
633void MemRegion::printPretty(raw_ostream &os) const {
634 assert(canPrintPretty() && "This region cannot be printed pretty.");
635 os << "'";
637 os << "'";
638}
639
640void MemRegion::printPrettyAsExpr(raw_ostream &) const {
641 llvm_unreachable("This region cannot be printed pretty.");
642}
643
644bool NonParamVarRegion::canPrintPrettyAsExpr() const { return true; }
645
646void NonParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
647 os << getDecl()->getName();
648}
649
650bool ParamVarRegion::canPrintPrettyAsExpr() const { return true; }
651
652void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
653 assert(getDecl() &&
654 "`ParamVarRegion` support functions without `Decl` not implemented"
655 " yet.");
656 os << getDecl()->getName();
657}
658
660 return true;
661}
662
663void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
664 os << getDecl()->getName();
665}
666
668 return true;
669}
670
673}
674
675void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
676 assert(canPrintPrettyAsExpr());
678 os << "." << getDecl()->getName();
679}
680
681void FieldRegion::printPretty(raw_ostream &os) const {
682 if (canPrintPrettyAsExpr()) {
683 os << "\'";
685 os << "'";
686 } else {
687 os << "field " << "\'" << getDecl()->getName() << "'";
688 }
689}
690
693}
694
695void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
697}
698
701}
702
703void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
705}
706
707std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
708 std::string VariableName;
709 std::string ArrayIndices;
710 const MemRegion *R = this;
711 SmallString<50> buf;
712 llvm::raw_svector_ostream os(buf);
713
714 // Obtain array indices to add them to the variable name.
715 const ElementRegion *ER = nullptr;
716 while ((ER = R->getAs<ElementRegion>())) {
717 // Index is a ConcreteInt.
718 if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
720 CI->getValue().toString(Idx);
721 ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
722 }
723 // Index is symbolic, but may have a descriptive name.
724 else {
725 auto SI = ER->getIndex().getAs<nonloc::SymbolVal>();
726 if (!SI)
727 return "";
728
729 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
730 if (!OR)
731 return "";
732
733 std::string Idx = OR->getDescriptiveName(false);
734 if (Idx.empty())
735 return "";
736
737 ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
738 }
739 R = ER->getSuperRegion();
740 }
741
742 // Get variable name.
743 if (R && R->canPrintPrettyAsExpr()) {
744 R->printPrettyAsExpr(os);
745 if (UseQuotes)
746 return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
747 else
748 return (llvm::Twine(os.str()) + ArrayIndices).str();
749 }
750
751 return VariableName;
752}
753
755 // Check for more specific regions first.
756 if (auto *FR = dyn_cast<FieldRegion>(this)) {
757 return FR->getDecl()->getSourceRange();
758 }
759
760 if (auto *VR = dyn_cast<VarRegion>(this->getBaseRegion())) {
761 return VR->getDecl()->getSourceRange();
762 }
763
764 // Return invalid source range (can be checked by client).
765 return {};
766}
767
768//===----------------------------------------------------------------------===//
769// MemRegionManager methods.
770//===----------------------------------------------------------------------===//
771
773 SValBuilder &SVB) const {
774 const auto *SR = cast<SubRegion>(MR);
775 SymbolManager &SymMgr = SVB.getSymbolManager();
776
777 switch (SR->getKind()) {
778 case MemRegion::AllocaRegionKind:
779 case MemRegion::SymbolicRegionKind:
780 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
781 case MemRegion::StringRegionKind:
782 return SVB.makeIntVal(
783 cast<StringRegion>(SR)->getStringLiteral()->getByteLength() + 1,
784 SVB.getArrayIndexType());
785 case MemRegion::CompoundLiteralRegionKind:
786 case MemRegion::CXXBaseObjectRegionKind:
787 case MemRegion::CXXDerivedObjectRegionKind:
788 case MemRegion::CXXTempObjectRegionKind:
789 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
790 case MemRegion::CXXThisRegionKind:
791 case MemRegion::ObjCIvarRegionKind:
792 case MemRegion::NonParamVarRegionKind:
793 case MemRegion::ParamVarRegionKind:
794 case MemRegion::ElementRegionKind:
795 case MemRegion::ObjCStringRegionKind: {
796 QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
797 if (isa<VariableArrayType>(Ty))
798 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
799
800 if (Ty->isIncompleteType())
801 return UnknownVal();
802
803 return getElementExtent(Ty, SVB);
804 }
805 case MemRegion::FieldRegionKind: {
806 // Force callers to deal with bitfields explicitly.
807 if (cast<FieldRegion>(SR)->getDecl()->isBitField())
808 return UnknownVal();
809
810 QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
811 const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
812
813 // We currently don't model flexible array members (FAMs), which are:
814 // - int array[]; of IncompleteArrayType
815 // - int array[0]; of ConstantArrayType with size 0
816 // - int array[1]; of ConstantArrayType with size 1
817 // https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
818 const auto isFlexibleArrayMemberCandidate =
819 [this](const ArrayType *AT) -> bool {
820 if (!AT)
821 return false;
822
823 auto IsIncompleteArray = [](const ArrayType *AT) {
824 return isa<IncompleteArrayType>(AT);
825 };
826 auto IsArrayOfZero = [](const ArrayType *AT) {
827 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
828 return CAT && CAT->isZeroSize();
829 };
830 auto IsArrayOfOne = [](const ArrayType *AT) {
831 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
832 return CAT && CAT->getSize() == 1;
833 };
834
836 const FAMKind StrictFlexArraysLevel =
837 Ctx.getLangOpts().getStrictFlexArraysLevel();
838
839 // "Default": Any trailing array member is a FAM.
840 // Since we cannot tell at this point if this array is a trailing member
841 // or not, let's just do the same as for "OneZeroOrIncomplete".
842 if (StrictFlexArraysLevel == FAMKind::Default)
843 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
844
845 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
846 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
847
848 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
849 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
850
851 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
852 return IsIncompleteArray(AT);
853 };
854
855 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
856 return UnknownVal();
857
858 return Size;
859 }
860 // FIXME: The following are being used in 'SimpleSValBuilder' and in
861 // 'ArrayBoundChecker::checkLocation' because there is no symbol to
862 // represent the regions more appropriately.
863 case MemRegion::BlockDataRegionKind:
864 case MemRegion::BlockCodeRegionKind:
865 case MemRegion::FunctionCodeRegionKind:
866 return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
867 default:
868 llvm_unreachable("Unhandled region");
869 }
870}
871
872template <typename REG>
873const REG *MemRegionManager::LazyAllocate(REG*& region) {
874 if (!region) {
875 region = new (A) REG(*this);
876 }
877
878 return region;
879}
880
881template <typename REG, typename ARG>
882const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
883 if (!region) {
884 region = new (A) REG(this, a);
885 }
886
887 return region;
888}
889
892 assert(STC);
893 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
894
895 if (R)
896 return R;
897
898 R = new (A) StackLocalsSpaceRegion(*this, STC);
899 return R;
900}
901
904 assert(STC);
905 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
906
907 if (R)
908 return R;
909
910 R = new (A) StackArgumentsSpaceRegion(*this, STC);
911 return R;
912}
913
916 const CodeTextRegion *CR) {
917 if (!CR) {
918 if (K == MemRegion::GlobalSystemSpaceRegionKind)
919 return LazyAllocate(SystemGlobals);
920 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
921 return LazyAllocate(ImmutableGlobals);
922 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
923 return LazyAllocate(InternalGlobals);
924 }
925
926 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
927 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
928 if (R)
929 return R;
930
931 R = new (A) StaticGlobalSpaceRegion(*this, CR);
932 return R;
933}
934
936 return LazyAllocate(heap);
937}
938
940 return LazyAllocate(unknown);
941}
942
944 return LazyAllocate(code);
945}
946
947//===----------------------------------------------------------------------===//
948// Constructing regions.
949//===----------------------------------------------------------------------===//
950
952 return getSubRegion<StringRegion>(
953 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
954}
955
956const ObjCStringRegion *
958 return getSubRegion<ObjCStringRegion>(
959 Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
960}
961
962/// Look through a chain of LocationContexts to either find the
963/// StackFrameContext that matches a DeclContext, or find a VarRegion
964/// for a variable captured by a block.
965static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
967 const DeclContext *DC,
968 const VarDecl *VD) {
969 while (LC) {
970 if (const auto *SFC = dyn_cast<StackFrameContext>(LC)) {
971 if (cast<DeclContext>(SFC->getDecl()) == DC)
972 return SFC;
973 }
974 if (const auto *BC = dyn_cast<BlockInvocationContext>(LC)) {
975 const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
976 // FIXME: This can be made more efficient.
977 for (auto Var : BR->referenced_vars()) {
978 const TypedValueRegion *OrigR = Var.getOriginalRegion();
979 if (const auto *VR = dyn_cast<VarRegion>(OrigR)) {
980 if (VR->getDecl() == VD)
981 return cast<VarRegion>(Var.getCapturedRegion());
982 }
983 }
984 }
985
986 LC = LC->getParent();
987 }
988 return (const StackFrameContext *)nullptr;
989}
990
992 const LocationContext *LC) {
993 const auto *PVD = dyn_cast<ParmVarDecl>(D);
994 if (PVD) {
995 unsigned Index = PVD->getFunctionScopeIndex();
996 const StackFrameContext *SFC = LC->getStackFrame();
997 const Stmt *CallSite = SFC->getCallSite();
998 if (CallSite) {
999 const Decl *D = SFC->getDecl();
1000 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1001 if (Index < FD->param_size() && FD->parameters()[Index] == PVD)
1002 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1004 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
1005 if (Index < BD->param_size() && BD->parameters()[Index] == PVD)
1006 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1008 } else {
1009 return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index,
1011 }
1012 }
1013 }
1014
1015 D = D->getCanonicalDecl();
1016 const MemRegion *sReg = nullptr;
1017
1018 if (D->hasGlobalStorage() && !D->isStaticLocal()) {
1019 QualType Ty = D->getType();
1020 assert(!Ty.isNull());
1021 if (Ty.isConstQualified()) {
1022 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1023 } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
1024 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
1025 } else {
1026 sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
1027 }
1028
1029 // Finally handle static locals.
1030 } else {
1031 // FIXME: Once we implement scope handling, we will need to properly lookup
1032 // 'D' to the proper LocationContext.
1033 const DeclContext *DC = D->getDeclContext();
1034 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
1036
1037 if (V.is<const VarRegion*>())
1038 return V.get<const VarRegion*>();
1039
1040 const auto *STC = V.get<const StackFrameContext *>();
1041
1042 if (!STC) {
1043 // FIXME: Assign a more sensible memory space to static locals
1044 // we see from within blocks that we analyze as top-level declarations.
1045 sReg = getUnknownRegion();
1046 } else {
1047 if (D->hasLocalStorage()) {
1048 sReg =
1049 isa<ParmVarDecl, ImplicitParamDecl>(D)
1050 ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
1051 : static_cast<const MemRegion *>(getStackLocalsRegion(STC));
1052 }
1053 else {
1054 assert(D->isStaticLocal());
1055 const Decl *STCD = STC->getDecl();
1056 if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
1057 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1058 getFunctionCodeRegion(cast<NamedDecl>(STCD)));
1059 else if (const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1060 // FIXME: The fallback type here is totally bogus -- though it should
1061 // never be queried, it will prevent uniquing with the real
1062 // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
1063 // signature.
1064 QualType T;
1065 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
1066 T = TSI->getType();
1067 if (T.isNull())
1068 T = getContext().VoidTy;
1069 if (!T->getAs<FunctionType>()) {
1071 T = getContext().getFunctionType(T, std::nullopt, Ext);
1072 }
1074
1075 const BlockCodeRegion *BTR =
1077 STC->getAnalysisDeclContext());
1078 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1079 BTR);
1080 }
1081 else {
1082 sReg = getGlobalsRegion();
1083 }
1084 }
1085 }
1086 }
1087
1088 return getNonParamVarRegion(D, sReg);
1089}
1090
1091const NonParamVarRegion *
1093 const MemRegion *superR) {
1094 // Prefer the definition over the canonical decl as the canonical form.
1095 D = D->getCanonicalDecl();
1096 if (const VarDecl *Def = D->getDefinition())
1097 D = Def;
1098 return getSubRegion<NonParamVarRegion>(D, superR);
1099}
1100
1101const ParamVarRegion *
1102MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
1103 const LocationContext *LC) {
1104 const StackFrameContext *SFC = LC->getStackFrame();
1105 assert(SFC);
1106 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1108}
1109
1110const BlockDataRegion *
1112 const LocationContext *LC,
1113 unsigned blockCount) {
1114 const MemSpaceRegion *sReg = nullptr;
1115 const BlockDecl *BD = BC->getDecl();
1116 if (!BD->hasCaptures()) {
1117 // This handles 'static' blocks.
1118 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1119 }
1120 else {
1121 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1122
1123 // ARC managed blocks can be initialized on stack or directly in heap
1124 // depending on the implementations. So we initialize them with
1125 // UnknownRegion.
1126 if (!IsArcManagedBlock && LC) {
1127 // FIXME: Once we implement scope handling, we want the parent region
1128 // to be the scope.
1129 const StackFrameContext *STC = LC->getStackFrame();
1130 assert(STC);
1131 sReg = getStackLocalsRegion(STC);
1132 } else {
1133 // We allow 'LC' to be NULL for cases where want BlockDataRegions
1134 // without context-sensitivity.
1135 sReg = getUnknownRegion();
1136 }
1137 }
1138
1139 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
1140}
1141
1144 const LocationContext *LC) {
1145 const MemSpaceRegion *sReg = nullptr;
1146
1147 if (CL->isFileScope())
1148 sReg = getGlobalsRegion();
1149 else {
1150 const StackFrameContext *STC = LC->getStackFrame();
1151 assert(STC);
1152 sReg = getStackLocalsRegion(STC);
1153 }
1154
1155 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
1156}
1157
1158const ElementRegion *
1160 const SubRegion *superRegion,
1161 const ASTContext &Ctx) {
1162 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
1163
1164 llvm::FoldingSetNodeID ID;
1165 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
1166
1167 void *InsertPos;
1168 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1169 auto *R = cast_or_null<ElementRegion>(data);
1170
1171 if (!R) {
1172 R = new (A) ElementRegion(T, Idx, superRegion);
1173 Regions.InsertNode(R, InsertPos);
1174 }
1175
1176 return R;
1177}
1178
1179const FunctionCodeRegion *
1181 // To think: should we canonicalize the declaration here?
1182 return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
1183}
1184
1185const BlockCodeRegion *
1187 AnalysisDeclContext *AC) {
1188 return getSubRegion<BlockCodeRegion>(BD, locTy, AC, getCodeRegion());
1189}
1190
1191const SymbolicRegion *
1193 const MemSpaceRegion *MemSpace) {
1194 if (MemSpace == nullptr)
1195 MemSpace = getUnknownRegion();
1196 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1197}
1198
1200 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
1201}
1202
1203const FieldRegion*
1205 const SubRegion* superRegion){
1206 return getSubRegion<FieldRegion>(d, superRegion);
1207}
1208
1209const ObjCIvarRegion*
1211 const SubRegion* superRegion) {
1212 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1213}
1214
1217 LocationContext const *LC) {
1218 const StackFrameContext *SFC = LC->getStackFrame();
1219 assert(SFC);
1220 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
1221}
1222
1225 const Expr *Ex, const ValueDecl *VD, const LocationContext *LC) {
1226 const StackFrameContext *SFC = LC->getStackFrame();
1227 assert(SFC);
1228 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1229 Ex, VD, getStackLocalsRegion(SFC));
1230}
1231
1234 const Expr *Ex, const ValueDecl *VD) {
1235 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1236 Ex, VD,
1237 getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
1238}
1239
1240/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
1241/// class of the type of \p Super.
1242static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
1243 const TypedValueRegion *Super,
1244 bool IsVirtual) {
1245 BaseClass = BaseClass->getCanonicalDecl();
1246
1248 if (!Class)
1249 return true;
1250
1251 if (IsVirtual)
1252 return Class->isVirtuallyDerivedFrom(BaseClass);
1253
1254 for (const auto &I : Class->bases()) {
1255 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1256 return true;
1257 }
1258
1259 return false;
1260}
1261
1262const CXXBaseObjectRegion *
1264 const SubRegion *Super,
1265 bool IsVirtual) {
1266 if (isa<TypedValueRegion>(Super)) {
1267 assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual));
1268 (void)&isValidBaseClass;
1269
1270 if (IsVirtual) {
1271 // Virtual base regions should not be layered, since the layout rules
1272 // are different.
1273 while (const auto *Base = dyn_cast<CXXBaseObjectRegion>(Super))
1274 Super = cast<SubRegion>(Base->getSuperRegion());
1275 assert(Super && !isa<MemSpaceRegion>(Super));
1276 }
1277 }
1278
1279 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1280}
1281
1284 const SubRegion *Super) {
1285 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1286}
1287
1288const CXXThisRegion*
1290 const LocationContext *LC) {
1291 const auto *PT = thisPointerTy->getAs<PointerType>();
1292 assert(PT);
1293 // Inside the body of the operator() of a lambda a this expr might refer to an
1294 // object in one of the parent location contexts.
1295 const auto *D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1296 // FIXME: when operator() of lambda is analyzed as a top level function and
1297 // 'this' refers to a this to the enclosing scope, there is no right region to
1298 // return.
1299 while (!LC->inTopFrame() && (!D || D->isStatic() ||
1300 PT != D->getThisType()->getAs<PointerType>())) {
1301 LC = LC->getParent();
1302 D = dyn_cast<CXXMethodDecl>(LC->getDecl());
1303 }
1304 const StackFrameContext *STC = LC->getStackFrame();
1305 assert(STC);
1306 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
1307}
1308
1309const AllocaRegion*
1311 const LocationContext *LC) {
1312 const StackFrameContext *STC = LC->getStackFrame();
1313 assert(STC);
1314 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
1315}
1316
1318 const MemRegion *R = this;
1319 const auto *SR = dyn_cast<SubRegion>(this);
1320
1321 while (SR) {
1322 R = SR->getSuperRegion();
1323 SR = dyn_cast<SubRegion>(R);
1324 }
1325
1326 return cast<MemSpaceRegion>(R);
1327}
1328
1330 return isa<StackSpaceRegion>(getMemorySpace());
1331}
1332
1334 return isa<StackLocalsSpaceRegion>(getMemorySpace());
1335}
1336
1338 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
1339}
1340
1341// Strips away all elements and fields.
1342// Returns the base region of them.
1344 const MemRegion *R = this;
1345 while (true) {
1346 switch (R->getKind()) {
1347 case MemRegion::ElementRegionKind:
1348 case MemRegion::FieldRegionKind:
1349 case MemRegion::ObjCIvarRegionKind:
1350 case MemRegion::CXXBaseObjectRegionKind:
1351 case MemRegion::CXXDerivedObjectRegionKind:
1352 R = cast<SubRegion>(R)->getSuperRegion();
1353 continue;
1354 default:
1355 break;
1356 }
1357 break;
1358 }
1359 return R;
1360}
1361
1362// Returns the region of the root class of a C++ class hierarchy.
1364 const MemRegion *R = this;
1365 while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1366 R = BR->getSuperRegion();
1367 return R;
1368}
1369
1371 return false;
1372}
1373
1374//===----------------------------------------------------------------------===//
1375// View handling.
1376//===----------------------------------------------------------------------===//
1377
1378const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {
1379 const MemRegion *R = this;
1380 while (true) {
1381 switch (R->getKind()) {
1382 case ElementRegionKind: {
1383 const auto *ER = cast<ElementRegion>(R);
1384 if (!ER->getIndex().isZeroConstant())
1385 return R;
1386 R = ER->getSuperRegion();
1387 break;
1388 }
1389 case CXXBaseObjectRegionKind:
1390 case CXXDerivedObjectRegionKind:
1391 if (!StripBaseAndDerivedCasts)
1392 return R;
1393 R = cast<TypedValueRegion>(R)->getSuperRegion();
1394 break;
1395 default:
1396 return R;
1397 }
1398 }
1399}
1400
1402 const auto *SubR = dyn_cast<SubRegion>(this);
1403
1404 while (SubR) {
1405 if (const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1406 return SymR;
1407 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1408 }
1409 return nullptr;
1410}
1411
1413 int64_t offset = 0;
1414 const ElementRegion *ER = this;
1415 const MemRegion *superR = nullptr;
1416 ASTContext &C = getContext();
1417
1418 // FIXME: Handle multi-dimensional arrays.
1419
1420 while (ER) {
1421 superR = ER->getSuperRegion();
1422
1423 // FIXME: generalize to symbolic offsets.
1424 SVal index = ER->getIndex();
1425 if (auto CI = index.getAs<nonloc::ConcreteInt>()) {
1426 // Update the offset.
1427 int64_t i = CI->getValue().getSExtValue();
1428
1429 if (i != 0) {
1430 QualType elemType = ER->getElementType();
1431
1432 // If we are pointing to an incomplete type, go no further.
1433 if (elemType->isIncompleteType()) {
1434 superR = ER;
1435 break;
1436 }
1437
1438 int64_t size = C.getTypeSizeInChars(elemType).getQuantity();
1439 if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1440 offset = *NewOffset;
1441 } else {
1442 LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: "
1443 << "offset overflowing, returning unknown\n");
1444
1445 return nullptr;
1446 }
1447 }
1448
1449 // Go to the next ElementRegion (if any).
1450 ER = dyn_cast<ElementRegion>(superR);
1451 continue;
1452 }
1453
1454 return nullptr;
1455 }
1456
1457 assert(superR && "super region cannot be NULL");
1458 return RegionRawOffset(superR, CharUnits::fromQuantity(offset));
1459}
1460
1461/// Returns true if \p Base is an immediate base class of \p Child
1462static bool isImmediateBase(const CXXRecordDecl *Child,
1463 const CXXRecordDecl *Base) {
1464 assert(Child && "Child must not be null");
1465 // Note that we do NOT canonicalize the base class here, because
1466 // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1467 // so be it; at least we won't crash.
1468 for (const auto &I : Child->bases()) {
1469 if (I.getType()->getAsCXXRecordDecl() == Base)
1470 return true;
1471 }
1472
1473 return false;
1474}
1475
1477 const MemRegion *SymbolicOffsetBase = nullptr;
1478 int64_t Offset = 0;
1479
1480 while (true) {
1481 switch (R->getKind()) {
1482 case MemRegion::CodeSpaceRegionKind:
1483 case MemRegion::StackLocalsSpaceRegionKind:
1484 case MemRegion::StackArgumentsSpaceRegionKind:
1485 case MemRegion::HeapSpaceRegionKind:
1486 case MemRegion::UnknownSpaceRegionKind:
1487 case MemRegion::StaticGlobalSpaceRegionKind:
1488 case MemRegion::GlobalInternalSpaceRegionKind:
1489 case MemRegion::GlobalSystemSpaceRegionKind:
1490 case MemRegion::GlobalImmutableSpaceRegionKind:
1491 // Stores can bind directly to a region space to set a default value.
1492 assert(Offset == 0 && !SymbolicOffsetBase);
1493 goto Finish;
1494
1495 case MemRegion::FunctionCodeRegionKind:
1496 case MemRegion::BlockCodeRegionKind:
1497 case MemRegion::BlockDataRegionKind:
1498 // These will never have bindings, but may end up having values requested
1499 // if the user does some strange casting.
1500 if (Offset != 0)
1501 SymbolicOffsetBase = R;
1502 goto Finish;
1503
1504 case MemRegion::SymbolicRegionKind:
1505 case MemRegion::AllocaRegionKind:
1506 case MemRegion::CompoundLiteralRegionKind:
1507 case MemRegion::CXXThisRegionKind:
1508 case MemRegion::StringRegionKind:
1509 case MemRegion::ObjCStringRegionKind:
1510 case MemRegion::NonParamVarRegionKind:
1511 case MemRegion::ParamVarRegionKind:
1512 case MemRegion::CXXTempObjectRegionKind:
1513 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1514 // Usual base regions.
1515 goto Finish;
1516
1517 case MemRegion::ObjCIvarRegionKind:
1518 // This is a little strange, but it's a compromise between
1519 // ObjCIvarRegions having unknown compile-time offsets (when using the
1520 // non-fragile runtime) and yet still being distinct, non-overlapping
1521 // regions. Thus we treat them as "like" base regions for the purposes
1522 // of computing offsets.
1523 goto Finish;
1524
1525 case MemRegion::CXXBaseObjectRegionKind: {
1526 const auto *BOR = cast<CXXBaseObjectRegion>(R);
1527 R = BOR->getSuperRegion();
1528
1529 QualType Ty;
1530 bool RootIsSymbolic = false;
1531 if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1532 Ty = TVR->getDesugaredValueType(R->getContext());
1533 } else if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1534 // If our base region is symbolic, we don't know what type it really is.
1535 // Pretend the type of the symbol is the true dynamic type.
1536 // (This will at least be self-consistent for the life of the symbol.)
1537 Ty = SR->getPointeeStaticType();
1538 RootIsSymbolic = true;
1539 }
1540
1541 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1542 if (!Child) {
1543 // We cannot compute the offset of the base class.
1544 SymbolicOffsetBase = R;
1545 } else {
1546 if (RootIsSymbolic) {
1547 // Base layers on symbolic regions may not be type-correct.
1548 // Double-check the inheritance here, and revert to a symbolic offset
1549 // if it's invalid (e.g. due to a reinterpret_cast).
1550 if (BOR->isVirtual()) {
1551 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1552 SymbolicOffsetBase = R;
1553 } else {
1554 if (!isImmediateBase(Child, BOR->getDecl()))
1555 SymbolicOffsetBase = R;
1556 }
1557 }
1558 }
1559
1560 // Don't bother calculating precise offsets if we already have a
1561 // symbolic offset somewhere in the chain.
1562 if (SymbolicOffsetBase)
1563 continue;
1564
1565 CharUnits BaseOffset;
1566 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1567 if (BOR->isVirtual())
1568 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1569 else
1570 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1571
1572 // The base offset is in chars, not in bits.
1573 Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
1574 break;
1575 }
1576
1577 case MemRegion::CXXDerivedObjectRegionKind: {
1578 // TODO: Store the base type in the CXXDerivedObjectRegion and use it.
1579 goto Finish;
1580 }
1581
1582 case MemRegion::ElementRegionKind: {
1583 const auto *ER = cast<ElementRegion>(R);
1584 R = ER->getSuperRegion();
1585
1586 QualType EleTy = ER->getValueType();
1587 if (EleTy->isIncompleteType()) {
1588 // We cannot compute the offset of the base class.
1589 SymbolicOffsetBase = R;
1590 continue;
1591 }
1592
1593 SVal Index = ER->getIndex();
1594 if (std::optional<nonloc::ConcreteInt> CI =
1595 Index.getAs<nonloc::ConcreteInt>()) {
1596 // Don't bother calculating precise offsets if we already have a
1597 // symbolic offset somewhere in the chain.
1598 if (SymbolicOffsetBase)
1599 continue;
1600
1601 int64_t i = CI->getValue().getSExtValue();
1602 // This type size is in bits.
1603 Offset += i * R->getContext().getTypeSize(EleTy);
1604 } else {
1605 // We cannot compute offset for non-concrete index.
1606 SymbolicOffsetBase = R;
1607 }
1608 break;
1609 }
1610 case MemRegion::FieldRegionKind: {
1611 const auto *FR = cast<FieldRegion>(R);
1612 R = FR->getSuperRegion();
1613 assert(R);
1614
1615 const RecordDecl *RD = FR->getDecl()->getParent();
1616 if (RD->isUnion() || !RD->isCompleteDefinition()) {
1617 // We cannot compute offset for incomplete type.
1618 // For unions, we could treat everything as offset 0, but we'd rather
1619 // treat each field as a symbolic offset so they aren't stored on top
1620 // of each other, since we depend on things in typed regions actually
1621 // matching their types.
1622 SymbolicOffsetBase = R;
1623 }
1624
1625 // Don't bother calculating precise offsets if we already have a
1626 // symbolic offset somewhere in the chain.
1627 if (SymbolicOffsetBase)
1628 continue;
1629
1630 // Get the field number.
1631 unsigned idx = 0;
1633 FE = RD->field_end(); FI != FE; ++FI, ++idx) {
1634 if (FR->getDecl() == *FI)
1635 break;
1636 }
1637 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1638 // This is offset in bits.
1639 Offset += Layout.getFieldOffset(idx);
1640 break;
1641 }
1642 }
1643 }
1644
1645 Finish:
1646 if (SymbolicOffsetBase)
1647 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1648 return RegionOffset(R, Offset);
1649}
1650
1652 if (!cachedOffset)
1653 cachedOffset = calculateOffset(this);
1654 return *cachedOffset;
1655}
1656
1657//===----------------------------------------------------------------------===//
1658// BlockDataRegion
1659//===----------------------------------------------------------------------===//
1660
1661std::pair<const VarRegion *, const VarRegion *>
1662BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1664 const VarRegion *VR = nullptr;
1665 const VarRegion *OriginalVR = nullptr;
1666
1667 if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1668 VR = MemMgr.getNonParamVarRegion(VD, this);
1669 OriginalVR = MemMgr.getVarRegion(VD, LC);
1670 }
1671 else {
1672 if (LC) {
1673 VR = MemMgr.getVarRegion(VD, LC);
1674 OriginalVR = VR;
1675 }
1676 else {
1677 VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion());
1678 OriginalVR = MemMgr.getVarRegion(VD, LC);
1679 }
1680 }
1681 return std::make_pair(VR, OriginalVR);
1682}
1683
1684void BlockDataRegion::LazyInitializeReferencedVars() {
1685 if (ReferencedVars)
1686 return;
1687
1689 const auto &ReferencedBlockVars = AC->getReferencedBlockVars(BC->getDecl());
1690 auto NumBlockVars =
1691 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1692
1693 if (NumBlockVars == 0) {
1694 ReferencedVars = (void*) 0x1;
1695 return;
1696 }
1697
1699 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1700 BumpVectorContext BC(A);
1701
1702 using VarVec = BumpVector<const MemRegion *>;
1703
1704 auto *BV = new (A) VarVec(BC, NumBlockVars);
1705 auto *BVOriginal = new (A) VarVec(BC, NumBlockVars);
1706
1707 for (const auto *VD : ReferencedBlockVars) {
1708 const VarRegion *VR = nullptr;
1709 const VarRegion *OriginalVR = nullptr;
1710 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1711 assert(VR);
1712 assert(OriginalVR);
1713 BV->push_back(VR, BC);
1714 BVOriginal->push_back(OriginalVR, BC);
1715 }
1716
1717 ReferencedVars = BV;
1718 OriginalVars = BVOriginal;
1719}
1720
1723 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1724
1725 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
1726
1727 if (Vec == (void*) 0x1)
1728 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1729
1730 auto *VecOriginal =
1731 static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
1732
1734 VecOriginal->begin());
1735}
1736
1739 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1740
1741 auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
1742
1743 if (Vec == (void*) 0x1)
1744 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
1745
1746 auto *VecOriginal =
1747 static_cast<BumpVector<const MemRegion *> *>(OriginalVars);
1748
1750 VecOriginal->end());
1751}
1752
1753llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1755 return llvm::make_range(referenced_vars_begin(), referenced_vars_end());
1756}
1757
1759 for (const auto &I : referenced_vars()) {
1760 if (I.getCapturedRegion() == R)
1761 return I.getOriginalRegion();
1762 }
1763 return nullptr;
1764}
1765
1766//===----------------------------------------------------------------------===//
1767// RegionAndSymbolInvalidationTraits
1768//===----------------------------------------------------------------------===//
1769
1771 InvalidationKinds IK) {
1772 SymTraitsMap[Sym] |= IK;
1773}
1774
1776 InvalidationKinds IK) {
1777 assert(MR);
1778 if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
1779 setTrait(SR->getSymbol(), IK);
1780 else
1781 MRTraitsMap[MR] |= IK;
1782}
1783
1785 InvalidationKinds IK) const {
1786 const_symbol_iterator I = SymTraitsMap.find(Sym);
1787 if (I != SymTraitsMap.end())
1788 return I->second & IK;
1789
1790 return false;
1791}
1792
1794 InvalidationKinds IK) const {
1795 if (!MR)
1796 return false;
1797
1798 if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
1799 return hasTrait(SR->getSymbol(), IK);
1800
1801 const_region_iterator I = MRTraitsMap.find(MR);
1802 if (I != MRTraitsMap.end())
1803 return I->second & IK;
1804
1805 return false;
1806}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3301
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
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:966
static bool isImmediateBase(const CXXRecordDecl *Child, const CXXRecordDecl *Base)
Returns true if Base is an immediate base class of Child.
Definition: MemRegion.cpp:1462
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:1242
static RegionOffset calculateOffset(const MemRegion *R)
Definition: MemRegion.cpp:1476
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:185
SourceManager & getSourceManager()
Definition: ASTContext.h:708
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:2591
const LangOptions & getLangOpts() const
Definition: ASTContext.h:778
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:2357
CanQualType VoidTy
Definition: ASTContext.h:1094
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:1578
uint64_t getCharWidth() const
Return the size of the character type, in bits.
Definition: ASTContext.h:2361
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:3534
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4496
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:4615
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:4582
TypeSourceInfo * getSignatureAsWritten() const
Definition: Decl.h:4579
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:523
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:3413
bool isFileScope() const
Definition: Expr.h:3440
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2342
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1432
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2062
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
int64_t getID() const
Definition: DeclBase.cpp:1150
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getDeclContext()
Definition: DeclBase.h:454
bool hasAttr() const
Definition: DeclBase.h:583
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:3059
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4272
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:1950
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
Represents a parameter to a function.
Definition: Decl.h:1761
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3155
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:7445
Represents a struct/union/class.
Definition: Decl.h:4170
field_iterator field_end() const
Definition: Decl.h:4379
field_iterator field_begin() const
Definition: Decl.cpp:5065
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:1773
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3689
bool isUnion() const
Definition: Decl.h:3792
A container of type source information.
Definition: Type.h:7343
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1881
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2361
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8143
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2247
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1213
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2356
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1195
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1171
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
Definition: MemRegion.h:473
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:626
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
Definition: MemRegion.h:656
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:488
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl * getDecl() const
Definition: MemRegion.h:651
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:374
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:673
const VarRegion * getOriginalRegion(const VarRegion *VR) const
Return the original region for a captured region, if one exists.
Definition: MemRegion.cpp:1758
referenced_vars_iterator referenced_vars_begin() const
Definition: MemRegion.cpp:1722
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockCodeRegion * getCodeRegion() const
Definition: MemRegion.h:700
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:390
referenced_vars_iterator referenced_vars_end() const
Definition: MemRegion.cpp:1738
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:492
llvm::iterator_range< referenced_vars_iterator > referenced_vars() const
Definition: MemRegion.cpp:1754
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
Definition: MemRegion.cpp:695
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1322
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:691
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:703
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:699
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1365
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:1293
QualType getValueType() const override
Definition: MemRegion.h:1254
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:1069
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:226
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:577
CompoundLiteralRegion - A memory region representing a compound literal.
Definition: MemRegion.h:895
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:1194
QualType getElementType() const
Definition: MemRegion.h:1218
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:351
NonLoc getIndex() const
Definition: MemRegion.h:1214
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
Definition: MemRegion.cpp:1412
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:675
bool canPrintPretty() const override
Returns true if this region can be printed in a user-friendly way.
Definition: MemRegion.cpp:667
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:671
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:681
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: MemRegion.cpp:291
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
Definition: MemRegion.h:1120
FunctionCodeRegion - A region that represents code texts of function.
Definition: MemRegion.h:579
const NamedDecl * getDecl() const
Definition: MemRegion.h:607
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:935
const StackArgumentsSpaceRegion * getStackArgumentsRegion(const StackFrameContext *STC)
getStackArgumentsRegion - Retrieve the memory region associated with function/method arguments of the...
Definition: MemRegion.cpp:903
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.
Definition: MemRegion.cpp:1289
llvm::BumpPtrAllocator & getAllocator()
Definition: MemRegion.h:1427
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
Definition: MemRegion.cpp:1186
const UnknownSpaceRegion * getUnknownRegion()
getUnknownRegion - Retrieve the memory region associated with unknown memory space.
Definition: MemRegion.cpp:939
const CXXDerivedObjectRegion * getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super)
Create a CXXDerivedObjectRegion with the given derived class for region Super.
Definition: MemRegion.cpp:1283
const CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC)
getCompoundLiteralRegion - Retrieve the region associated with a given CompoundLiteral.
Definition: MemRegion.cpp:1143
const FieldRegion * getFieldRegion(const FieldDecl *fd, const SubRegion *superRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
Definition: MemRegion.cpp:1204
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC)
getAllocaRegion - Retrieve a region associated with a call to alloca().
Definition: MemRegion.cpp:1310
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:1159
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:991
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:1092
const StackLocalsSpaceRegion * getStackLocalsRegion(const StackFrameContext *STC)
getStackLocalsRegion - Retrieve the memory region associated with the specified stack frame.
Definition: MemRegion.cpp:891
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:1210
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
Definition: MemRegion.cpp:1199
const ObjCStringRegion * getObjCStringRegion(const ObjCStringLiteral *Str)
Definition: MemRegion.cpp:957
const StringRegion * getStringRegion(const StringLiteral *Str)
Definition: MemRegion.cpp:951
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
Definition: MemRegion.cpp:772
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:1102
const CodeSpaceRegion * getCodeRegion()
Definition: MemRegion.cpp:943
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:1224
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
Definition: MemRegion.cpp:1216
const GlobalsSpaceRegion * getGlobalsRegion(MemRegion::Kind K=MemRegion::GlobalInternalSpaceRegionKind, const CodeTextRegion *R=nullptr)
getGlobalsRegion - Retrieve the memory region associated with global variables.
Definition: MemRegion.cpp:915
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
Definition: MemRegion.cpp:1192
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
Definition: MemRegion.cpp:1180
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:1111
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:1263
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
Definition: MemRegion.cpp:1233
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:96
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:1317
bool hasStackParametersStorage() const
Definition: MemRegion.cpp:1337
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
Definition: MemRegion.cpp:1651
bool hasStackStorage() const
Definition: MemRegion.cpp:1329
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1378
ASTContext & getContext() const
Definition: MemRegion.h:1615
std::string getDescriptiveName(bool UseQuotes=true) const
Get descriptive name for memory region.
Definition: MemRegion.cpp:707
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:1370
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:1401
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1343
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
Definition: MemRegion.cpp:633
virtual void printPrettyAsExpr(raw_ostream &os) const
Print the region as expression.
Definition: MemRegion.cpp:640
bool hasStackNonParametersStorage() const
Definition: MemRegion.cpp:1333
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:1383
Kind getKind() const
Definition: MemRegion.h:172
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:1363
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:754
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
Definition: MemRegion.h:203
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:644
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:646
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:562
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const override
Definition: MemRegion.h:1001
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:659
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:663
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:858
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:551
ParamVarRegion - Represents a region for paremters.
Definition: MemRegion.h:1029
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
Definition: MemRegion.cpp:650
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getOriginExpr() const
Definition: MemRegion.h:1046
const ParmVarDecl * getDecl() const override
TODO: What does this return?
Definition: MemRegion.cpp:200
unsigned getIndex() const
Definition: MemRegion.h:1047
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:652
InvalidationKinds
Describes different invalidation traits.
Definition: MemRegion.h:1637
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1784
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Definition: MemRegion.cpp:1770
Represent a region's offset within the top level base region.
Definition: MemRegion.h:63
static const int64_t Symbolic
Definition: MemRegion.h:73
CharUnits getOffset() const
Definition: MemRegion.h:1184
void dumpToStream(raw_ostream &os) const
Definition: MemRegion.cpp:573
const MemRegion * getRegion() const
Definition: MemRegion.h:1187
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:400
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:260
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:276
StringRegion - Region associated with a StringLiteral.
Definition: MemRegion.h:824
void dumpToStream(raw_ostream &os) const override
Definition: MemRegion.cpp:546
SubRegion - A region that subsets another larger region.
Definition: MemRegion.h:441
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
Definition: MemRegion.h:454
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:445
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:775
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:530
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:4751
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57