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