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