clang: lib/StaticAnalyzer/Core/MemRegion.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
51#include
52#include
53#include
54#include
55#include
56#include
57#include
58
59using namespace clang;
60using namespace ento;
61
62#define DEBUG_TYPE "MemRegion"
63
64
65
66
67
69 const auto *TyReg = llvm::dyn_cast(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(Regions.FindNodeOrInsertPos(ID, InsertPos));
80
81 if (!R) {
82 R = new (A) RegionTy(arg1, superRegion);
83 Regions.InsertNode(R, InsertPos);
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(Regions.FindNodeOrInsertPos(ID, InsertPos));
97
98 if (!R) {
99 R = new (A) RegionTy(arg1, arg2, superRegion);
100 Regions.InsertNode(R, InsertPos);
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(Regions.FindNodeOrInsertPos(ID, InsertPos));
116
117 if (!R) {
118 R = new (A) RegionTy(arg1, arg2, arg3, superRegion);
119 Regions.InsertNode(R, InsertPos);
121 }
122
123 return R;
124}
125
126
127
128
129
131
132
133
135
136
137
138
139
142 do {
143 if (r == R)
144 return true;
145 if (const auto *sr = dyn_cast(r))
146 r = sr->getSuperRegion();
147 else
148 break;
149 } while (r != nullptr);
150 return false;
151}
152
155 do {
157 if (const auto *sr = dyn_cast(superRegion)) {
158 r = sr;
159 continue;
160 }
162 } while (true);
163}
164
166 const auto *SSR = dyn_cast(getMemorySpace());
167 return SSR ? SSR->getStackFrame() : nullptr;
168}
169
172 const auto *SSR = dyn_cast(getMemorySpace());
173 return SSR ? SSR->getStackFrame() : nullptr;
174}
175
178 "A temporary object can only be allocated on the stack");
179 return cast(getMemorySpace())->getStackFrame();
180}
181
183 : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {
184 assert(IVD);
185}
186
188
191}
192
195}
196
199}
200
203 "`ParamVarRegion` support functions without `Decl` not implemented"
204 " yet.");
206}
207
210
211 if (const auto *FD = dyn_cast(D)) {
212 assert(Index < FD->param_size());
213 return FD->parameters()[Index];
214 } else if (const auto *BD = dyn_cast(D)) {
215 assert(Index < BD->param_size());
216 return BD->parameters()[Index];
217 } else if (const auto *MD = dyn_cast(D)) {
218 assert(Index < MD->param_size());
219 return MD->parameters()[Index];
220 } else if (const auto *CD = dyn_cast(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
230
231
233 ID.AddInteger(static_cast<unsigned>(getKind()));
234}
235
237 ID.AddInteger(static_cast<unsigned>(getKind()));
239}
240
242 ID.AddInteger(static_cast<unsigned>(getKind()));
244}
245
246void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
249 ID.AddInteger(static_cast<unsigned>(StringRegionKind));
250 ID.AddPointer(Str);
252}
253
254void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
257 ID.AddInteger(static_cast<unsigned>(ObjCStringRegionKind));
258 ID.AddPointer(Str);
260}
261
262void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
263 const Expr *Ex, unsigned cnt,
265 ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
266 ID.AddPointer(Ex);
267 ID.AddInteger(cnt);
269}
270
273}
274
276 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
277}
278
279void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
282 ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
283 ID.AddPointer(CL);
285}
286
287void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
290 ID.AddInteger(static_cast<unsigned>(CXXThisRegionKind));
291 ID.AddPointer(PT);
292 ID.AddPointer(sRegion);
293}
294
296 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
297}
298
301}
302
303void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
306 ID.AddInteger(static_cast<unsigned>(ObjCIvarRegionKind));
307 ID.AddPointer(ivd);
309}
310
313}
314
315void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
318 ID.AddInteger(static_cast<unsigned>(NonParamVarRegionKind));
319 ID.AddPointer(VD);
321}
322
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
337}
338
341 ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
342 ID.Add(sym);
343 ID.AddPointer(sreg);
344}
345
348}
349
350void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
353 ID.AddInteger(MemRegion::ElementRegionKind);
354 ID.Add(ElementType);
357}
358
360 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
361}
362
363void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
366 ID.AddInteger(MemRegion::FunctionCodeRegionKind);
367 ID.AddPointer(FD);
368}
369
371 FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
372}
373
374void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
378 ID.AddInteger(MemRegion::BlockCodeRegionKind);
379 ID.AddPointer(BD);
380}
381
383 BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
384}
385
386void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
389 unsigned BlkCount,
391 ID.AddInteger(MemRegion::BlockDataRegionKind);
392 ID.AddPointer(BC);
393 ID.AddPointer(LC);
394 ID.AddInteger(BlkCount);
395 ID.AddPointer(sReg);
396}
397
399 BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
400}
401
402void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
403 Expr const *Ex,
405 ID.AddPointer(Ex);
406 ID.AddPointer(sReg);
407}
408
411}
412
413void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
417 ID.AddPointer(E);
418 ID.AddPointer(D);
419 ID.AddPointer(sReg);
420}
421
423 llvm::FoldingSetNodeID &ID) const {
425}
426
427void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
429 bool IsVirtual,
431 ID.AddPointer(RD);
432 ID.AddBoolean(IsVirtual);
433 ID.AddPointer(SReg);
434}
435
438}
439
440void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
443 ID.AddPointer(RD);
444 ID.AddPointer(SReg);
445}
446
449}
450
451
452
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
471
472
475}
476
478 std::string s;
479 llvm::raw_string_ostream os(s);
481 return s;
482}
483
485 os << "";
486}
487
489 os << "alloca{S" << Ex->getID(getContext()) << ',' << Cnt << '}';
490}
491
494}
495
497 os << "block_code{" << static_cast<const void *>(this) << '}';
498}
499
501 os << "block_data{" << BC;
502 os << "; ";
504 os << "(" << Var.getCapturedRegion() << "<-" << Var.getOriginalRegion()
505 << ") ";
506 os << '}';
507}
508
510
512}
513
515 os << "temp_object{" << getValueType() << ", "
517}
518
520 os << "lifetime_extended_object{" << getValueType() << ", ";
522 os << ID->getName();
523 else
524 os << "D" << ExD->getID();
525 os << ", "
527}
528
531}
532
535}
536
538 os << "this";
539}
540
543 << '}';
544}
545
548}
549
552}
553
555 assert(Str != nullptr && "Expecting non-null StringLiteral");
557}
558
560 assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
562}
563
566 os << "Heap";
567 os << "SymRegion{" << sym << '}';
568}
569
572 os << ID->getName();
573 else
574 os << "NonParamVarRegion{D" << VD->getID() << '}';
575}
576
579}
580
583}
584
586 os << "CodeSpaceRegion";
587}
588
590 os << "StaticGlobalsMemSpace{" << CR << '}';
591}
592
594 os << "GlobalInternalSpaceRegion";
595}
596
598 os << "GlobalSystemSpaceRegion";
599}
600
602 os << "GlobalImmutableSpaceRegion";
603}
604
606 os << "HeapSpaceRegion";
607}
608
610 os << "UnknownSpaceRegion";
611}
612
614 os << "StackArgumentsSpaceRegion";
615}
616
618 os << "StackLocalsSpaceRegion";
619}
620
623 assert(PVD &&
624 "`ParamVarRegion` support functions without `Decl` not implemented"
625 " yet.");
627 os << ID->getName();
628 } else {
629 os << "ParamVarRegion{P" << PVD->getID() << '}';
630 }
631}
632
635}
636
638 return false;
639}
640
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
653 assert(canPrintPretty() && "This region cannot be printed pretty.");
654 os << "'";
656 os << "'";
657}
658
660 llvm_unreachable("This region cannot be printed pretty.");
661}
662
664
667}
668
670
673 "`ParamVarRegion` support functions without `Decl` not implemented"
674 " yet.");
676}
677
679 return true;
680}
681
684}
685
687 return true;
688}
689
692}
693
698}
699
702 os << "\'";
704 os << "'";
705 } else {
706 os << "field " << "\'" << getDecl()->getName() << "'";
707 }
708}
709
712}
713
716}
717
720}
721
724}
725
727 std::string VariableName;
728 std::string ArrayIndices;
731 llvm::raw_svector_ostream os(buf);
732
733
734 auto QuoteIfNeeded = [UseQuotes](const Twine &Subject) -> std::string {
735 if (UseQuotes)
736 return ("'" + Subject + "'").str();
737 return Subject.str();
738 };
739
740
743
746 CI->getValue()->toString(Idx);
747 ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
748 }
749
750 else {
752 if (!SI)
753 return "";
754
755 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
756 if (!OR)
757 return "";
758
760 if (Idx.empty())
761 return "";
762
763 ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
764 }
766 }
767
768
769 if (R) {
770
773 return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices);
774 }
775
776
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
790 if (auto *FR = dyn_cast(this)) {
791 return FR->getDecl()->getSourceRange();
792 }
793
794 if (auto *VR = dyn_cast(this->getBaseRegion())) {
795 return VR->getDecl()->getSourceRange();
796 }
797
798
799 return {};
800}
801
802
803
804
805
808 const auto *SR = cast(MR);
810
811 switch (SR->getKind()) {
812 case MemRegion::AllocaRegionKind:
813 case MemRegion::SymbolicRegionKind:
815 case MemRegion::StringRegionKind:
817 cast(SR)->getStringLiteral()->getByteLength() + 1,
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(SR)->getDesugaredValueType(Ctx);
831 if (isa(Ty))
833
836
838 }
839 case MemRegion::FieldRegionKind: {
840
841 if (cast(SR)->getDecl()->isBitField())
843
844 QualType Ty = cast(SR)->getDesugaredValueType(Ctx);
846
847
848
849
850
851
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(AT);
859 };
860 auto IsArrayOfZero = [](const ArrayType *AT) {
861 const auto *CAT = dyn_cast(AT);
862 return CAT && CAT->isZeroSize();
863 };
864 auto IsArrayOfOne = [](const ArrayType *AT) {
865 const auto *CAT = dyn_cast(AT);
866 return CAT && CAT->getSize() == 1;
867 };
868
870 const FAMKind StrictFlexArraysLevel =
871 Ctx.getLangOpts().getStrictFlexArraysLevel();
872
873
874
875
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)))
891
892 return Size;
893 }
894
895
896
897 case MemRegion::BlockDataRegionKind:
898 case MemRegion::BlockCodeRegionKind:
899 case MemRegion::FunctionCodeRegionKind:
901 default:
902 llvm_unreachable("Unhandled region");
903 }
904}
905
906template
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);
928
929 if (R)
930 return R;
931
933 return R;
934}
935
938 assert(STC);
940
941 if (R)
942 return R;
943
945 return R;
946}
947
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);
962 if (R)
963 return R;
964
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
983
984
986 return getSubRegion(
988}
989
992 return getSubRegion(
994}
995
996
997
998
999static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
1003 while (LC) {
1004 if (const auto *SFC = dyn_cast(LC)) {
1005 if (cast(SFC->getDecl()) == DC)
1006 return SFC;
1007 }
1008 if (const auto *BC = dyn_cast(LC)) {
1009 const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
1010
1011 for (auto Var : BR->referenced_vars()) {
1013 if (const auto *VR = dyn_cast(OrigR)) {
1014 if (VR->getDecl() == VD)
1015 return cast(Var.getCapturedRegion());
1016 }
1017 }
1018 }
1019
1021 }
1023}
1024
1027 const auto *PVD = dyn_cast(D);
1028 if (PVD) {
1029 unsigned Index = PVD->getFunctionScopeIndex();
1032 if (CallSite) {
1034 if (const auto *FD = dyn_cast(D)) {
1035 if (Index < FD->param_size() && FD->parameters()[Index] == PVD)
1036 return getSubRegion(cast(CallSite), Index,
1038 } else if (const auto *BD = dyn_cast(D)) {
1039 if (Index < BD->param_size() && BD->parameters()[Index] == PVD)
1040 return getSubRegion(cast(CallSite), Index,
1042 } else {
1043 return getSubRegion(cast(CallSite), Index,
1045 }
1046 }
1047 }
1048
1050 const MemRegion *sReg = nullptr;
1051
1052 if (D->hasGlobalStorage() && ->isStaticLocal()) {
1054 assert(!Ty.isNull());
1056 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1058 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
1059 } else {
1060 sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
1061 }
1062
1063
1064 } else {
1065
1066
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
1078
1080 } else {
1081 if (D->hasLocalStorage()) {
1082 sReg =
1083 isa<ParmVarDecl, ImplicitParamDecl>(D)
1086 }
1087 else {
1088 assert(D->isStaticLocal());
1089 const Decl *STCD = STC->getDecl();
1090 if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
1091 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1093 else if (const auto *BD = dyn_cast(STCD)) {
1094
1095
1096
1097
1100 T = TSI->getType();
1101 if (T.isNull())
1106 }
1108
1111 STC->getAnalysisDeclContext());
1112 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
1113 BTR);
1114 }
1115 else {
1117 }
1118 }
1119 }
1120 }
1121
1123}
1124
1128
1130 if (const VarDecl *Def = D->getDefinition())
1131 D = Def;
1132 return getSubRegion(D, superR);
1133}
1134
1139 assert(SFC);
1140 return getSubRegion(OriginExpr, Index,
1142}
1143
1147 unsigned blockCount) {
1151
1152 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
1153 }
1154 else {
1155 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1156
1157
1158
1159
1160 if (!IsArcManagedBlock && LC) {
1161
1162
1164 assert(STC);
1166 } else {
1167
1168
1170 }
1171 }
1172
1173 return getSubRegion(BC, LC, blockCount, sReg);
1174}
1175
1180
1183 else {
1185 assert(STC);
1187 }
1188
1189 return getSubRegion(CL, sReg);
1190}
1191
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(data);
1204
1205 if (!R) {
1207 Regions.InsertNode(R, InsertPos);
1208 }
1209
1210 return R;
1211}
1212
1215
1216 return getSubRegion(FD, getCodeRegion());
1217}
1218
1222 return getSubRegion(BD, locTy, AC, getCodeRegion());
1223}
1224
1228 if (MemSpace == nullptr)
1230 return getSubRegion(sym, MemSpace);
1231}
1232
1234 return getSubRegion(Sym, getHeapRegion());
1235}
1236
1240 return getSubRegion(d, superRegion);
1241}
1242
1246 return getSubRegion(d, superRegion);
1247}
1248
1253 assert(SFC);
1255}
1256
1261 assert(SFC);
1262 return getSubRegion(
1264}
1265
1269 return getSubRegion(
1270 Ex, VD,
1271 getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
1272}
1273
1274
1275
1278 bool IsVirtual) {
1280
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
1299 bool IsVirtual) {
1300 if (isa(Super)) {
1301 assert(isValidBaseClass(RD, cast(Super), IsVirtual));
1303
1304 if (IsVirtual) {
1305
1306
1307 while (const auto *Base = dyn_cast(Super))
1308 Super = cast(Base->getSuperRegion());
1309 assert(Super && !isa(Super));
1310 }
1311 }
1312
1313 return getSubRegion(RD, IsVirtual, Super);
1314}
1315
1319 return getSubRegion(RD, Super);
1320}
1321
1326 assert(PT);
1327
1328
1329 const auto *D = dyn_cast(LC->getDecl());
1330
1331
1332
1333 while (!LC->inTopFrame() && ( || D->isStatic() ||
1334 PT != D->getThisType()->getAs<PointerType>())) {
1336 D = dyn_cast(LC->getDecl());
1337 }
1339 assert(STC);
1341}
1342
1347 assert(STC);
1349}
1350
1353 const auto *SR = dyn_cast(this);
1354
1355 while (SR) {
1356 R = SR->getSuperRegion();
1357 SR = dyn_cast(R);
1358 }
1359
1360 return cast(R);
1361}
1362
1365}
1366
1368 return isa(getMemorySpace());
1369}
1370
1372 return isa(getMemorySpace());
1373}
1374
1375
1376
1379 while (true) {
1381 case MemRegion::ElementRegionKind:
1382 case MemRegion::FieldRegionKind:
1383 case MemRegion::ObjCIvarRegionKind:
1384 case MemRegion::CXXBaseObjectRegionKind:
1385 case MemRegion::CXXDerivedObjectRegionKind:
1386 R = cast(R)->getSuperRegion();
1387 continue;
1388 default:
1389 break;
1390 }
1391 break;
1392 }
1393 return R;
1394}
1395
1396
1399 while (const auto *BR = dyn_cast(R))
1400 R = BR->getSuperRegion();
1401 return R;
1402}
1403
1405 return false;
1406}
1407
1408
1409
1410
1411
1414 while (true) {
1416 case ElementRegionKind: {
1417 const auto *ER = cast(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(R)->getSuperRegion();
1428 break;
1429 default:
1430 return R;
1431 }
1432 }
1433}
1434
1436 const auto *SubR = dyn_cast(this);
1437
1438 while (SubR) {
1439 if (const auto *SymR = dyn_cast(SubR))
1440 return SymR;
1441 SubR = dyn_cast(SubR->getSuperRegion());
1442 }
1443 return nullptr;
1444}
1445
1447 int64_t offset = 0;
1449 const MemRegion *superR = nullptr;
1451
1452
1453
1454 while (ER) {
1456
1457
1460
1461 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1463
1464
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
1482 ER = dyn_cast(superR);
1483 continue;
1484 }
1485
1486 return nullptr;
1487 }
1488
1489 assert(superR && "super region cannot be NULL");
1491}
1492
1493
1496 assert(Child && "Child must not be null");
1497
1498
1499
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) {
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
1524 assert(Offset == 0 && !SymbolicOffsetBase);
1525 goto Finish;
1526
1527 case MemRegion::FunctionCodeRegionKind:
1528 case MemRegion::BlockCodeRegionKind:
1529 case MemRegion::BlockDataRegionKind:
1530
1531
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
1547 goto Finish;
1548
1549 case MemRegion::ObjCIvarRegionKind:
1550
1551
1552
1553
1554
1555 goto Finish;
1556
1557 case MemRegion::CXXBaseObjectRegionKind: {
1558 const auto *BOR = cast(R);
1559 R = BOR->getSuperRegion();
1560
1562 bool RootIsSymbolic = false;
1563 if (const auto *TVR = dyn_cast(R)) {
1564 Ty = TVR->getDesugaredValueType(R->getContext());
1565 } else if (const auto *SR = dyn_cast(R)) {
1566
1567
1568
1569 Ty = SR->getPointeeStaticType();
1570 RootIsSymbolic = true;
1571 }
1572
1574 if (!Child) {
1575
1576 SymbolicOffsetBase = R;
1577 } else {
1578 if (RootIsSymbolic) {
1579
1580
1581
1582 if (BOR->isVirtual()) {
1583 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1584 SymbolicOffsetBase = R;
1585 } else {
1587 SymbolicOffsetBase = R;
1588 }
1589 }
1590 }
1591
1592
1593
1594 if (SymbolicOffsetBase)
1595 continue;
1596
1599 if (BOR->isVirtual())
1601 else
1603
1604
1606 break;
1607 }
1608
1609 case MemRegion::CXXDerivedObjectRegionKind: {
1610
1611 goto Finish;
1612 }
1613
1614 case MemRegion::ElementRegionKind: {
1615 const auto *ER = cast(R);
1616 R = ER->getSuperRegion();
1617
1618 QualType EleTy = ER->getValueType();
1620
1621 SymbolicOffsetBase = R;
1622 continue;
1623 }
1624
1625 SVal Index = ER->getIndex();
1626 if (std::optionalnonloc::ConcreteInt CI =
1628
1629
1630 if (SymbolicOffsetBase)
1631 continue;
1632
1633 int64_t i = CI->getValue()->getSExtValue();
1634
1636 } else {
1637
1638 SymbolicOffsetBase = R;
1639 }
1640 break;
1641 }
1642 case MemRegion::FieldRegionKind: {
1643 const auto *FR = cast(R);
1644 R = FR->getSuperRegion();
1645 assert(R);
1646
1649
1650
1651
1652
1653
1654 SymbolicOffsetBase = R;
1655 }
1656
1657
1658
1659 if (SymbolicOffsetBase)
1660 continue;
1661
1662
1663 unsigned idx = 0;
1665 FE = RD->field_end(); FI != FE; ++FI, ++idx) {
1666 if (FR->getDecl() == *FI)
1667 break;
1668 }
1670
1672 break;
1673 }
1674 }
1675 }
1676
1677 Finish:
1678 if (SymbolicOffsetBase)
1681}
1682
1684 if (!cachedOffset)
1686 return *cachedOffset;
1687}
1688
1689
1690
1691
1692
1693std::pair<const VarRegion *, const VarRegion *>
1694BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1697 const VarRegion *OriginalVR = nullptr;
1698
1702 }
1703 else {
1704 if (LC) {
1706 OriginalVR = VR;
1707 }
1708 else {
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();
1733
1735
1736 auto *BV = new (A) VarVec(BC, NumBlockVars);
1737 auto *BVOriginal = new (A) VarVec(BC, NumBlockVars);
1738
1739 for (const auto *VD : ReferencedBlockVars) {
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
1758
1759 if (Vec == (void*) 0x1)
1761
1762 auto *VecOriginal =
1764
1766 VecOriginal->begin());
1767}
1768
1771 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1772
1774
1775 if (Vec == (void*) 0x1)
1777
1778 auto *VecOriginal =
1780
1782 VecOriginal->end());
1783}
1784
1785llvm::iterator_rangeBlockDataRegion::referenced\_vars\_iterator
1788}
1789
1792 if (I.getCapturedRegion() == R)
1793 return I.getOriginalRegion();
1794 }
1795 return nullptr;
1796}
1797
1798
1799
1800
1801
1804 SymTraitsMap[Sym] |= IK;
1805}
1806
1809 assert(MR);
1810 if (const auto *SR = dyn_cast(MR))
1811 setTrait(SR->getSymbol(), IK);
1812 else
1813 MRTraitsMap[MR] |= IK;
1814}
1815
1818 const_symbol_iterator I = SymTraitsMap.find(Sym);
1819 if (I != SymTraitsMap.end())
1820 return I->second & IK;
1821
1822 return false;
1823}
1824
1827 if (!MR)
1828 return false;
1829
1830 if (const auto *SR = dyn_cast(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.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static bool isAReferenceTypedValueRegion(const MemRegion *R)
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...
static bool isImmediateBase(const CXXRecordDecl *Child, const CXXRecordDecl *Base)
Returns true if Base is an immediate base class of Child.
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.
static RegionOffset calculateOffset(const MemRegion *R)
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 ...
SourceManager & getSourceManager()
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 ...
const LangOptions & getLangOpts() const
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.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
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.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
ArrayRef< ParmVarDecl * > parameters() const
TypeSourceInfo * getSignatureAsWritten() const
Represents a C++ struct/union/class.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CompoundLiteralExpr - [C99 6.5.2.5].
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
This represents one expression.
Represents a member of a struct/union/class.
FunctionType - C99 6.7.5.3 - Function Declarators.
One of these records is kept for each identifier that is lexed.
StrictFlexArraysLevelKind
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.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCStringLiteral, used for Objective-C string literals i.e.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
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.
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
StringLiteral - This represents a string literal expression, e.g.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A container of type source information.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs'.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
BlockCodeRegion - A region that represents code texts of blocks (closures).
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl * getDecl() const
void Profile(llvm::FoldingSetNodeID &ID) const override
BlockDataRegion - A region that represents a block instance.
const VarRegion * getOriginalRegion(const VarRegion *VR) const
Return the original region for a captured region, if one exists.
referenced_vars_iterator referenced_vars_begin() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockCodeRegion * getCodeRegion() const
void Profile(llvm::FoldingSetNodeID &ID) const override
referenced_vars_iterator referenced_vars_end() const
void dumpToStream(raw_ostream &os) const override
llvm::iterator_range< referenced_vars_iterator > referenced_vars() const
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
QualType getValueType() const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void dumpToStream(raw_ostream &os) const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
const StackFrameContext * getStackFrame() const
It might return null.
QualType getValueType() const override
QualType getValueType() const override
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrameContext * getStackFrame() const
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
CodeSpaceRegion - The memory space that holds the executable code of functions and blocks.
void dumpToStream(raw_ostream &os) const override
CompoundLiteralRegion - A memory region representing a compound literal.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
ElementRegion is used to represent both array elements and casts.
QualType getElementType() const
void Profile(llvm::FoldingSetNodeID &ID) const override
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
void dumpToStream(raw_ostream &os) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
bool canPrintPretty() const override
Returns true if this region can be printed in a user-friendly way.
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void dumpToStream(raw_ostream &os) const override
void printPretty(raw_ostream &os) const override
Print the region for use in diagnostics.
void Profile(llvm::FoldingSetNodeID &ID) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
FunctionCodeRegion - A region that represents code texts of function.
const NamedDecl * getDecl() const
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
const HeapSpaceRegion * getHeapRegion()
getHeapRegion - Retrieve the memory region associated with the generic "heap".
const StackArgumentsSpaceRegion * getStackArgumentsRegion(const StackFrameContext *STC)
getStackArgumentsRegion - Retrieve the memory region associated with function/method arguments of the...
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.
llvm::BumpPtrAllocator & getAllocator()
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
const UnknownSpaceRegion * getUnknownRegion()
getUnknownRegion - Retrieve the memory region associated with unknown memory space.
const CXXDerivedObjectRegion * getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super)
Create a CXXDerivedObjectRegion with the given derived class for region Super.
const CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC)
getCompoundLiteralRegion - Retrieve the region associated with a given CompoundLiteral.
const FieldRegion * getFieldRegion(const FieldDecl *fd, const SubRegion *superRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC)
getAllocaRegion - Retrieve a region associated with a call to alloca().
const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)
getElementRegion - Retrieve the memory region associated with the associated element type,...
const VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const NonParamVarRegion * getNonParamVarRegion(const VarDecl *VD, const MemRegion *superR)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const StackLocalsSpaceRegion * getStackLocalsRegion(const StackFrameContext *STC)
getStackLocalsRegion - Retrieve the memory region associated with the specified stack frame.
const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)
getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
const ObjCStringRegion * getObjCStringRegion(const ObjCStringLiteral *Str)
const StringRegion * getStringRegion(const StringLiteral *Str)
ASTContext & getContext()
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
const ParamVarRegion * getParamVarRegion(const Expr *OriginExpr, unsigned Index, const LocationContext *LC)
getParamVarRegion - Retrieve or create the memory region associated with a specified CallExpr,...
const CodeSpaceRegion * getCodeRegion()
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
const GlobalsSpaceRegion * getGlobalsRegion(MemRegion::Kind K=MemRegion::GlobalInternalSpaceRegionKind, const CodeTextRegion *R=nullptr)
getGlobalsRegion - Retrieve the memory region associated with global variables.
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
const CXXBaseObjectRegion * getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual)
Create a CXXBaseObjectRegion with the given base class for region Super.
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
MemRegion - The root abstract class for all memory regions.
virtual bool canPrintPrettyAsExpr() const
Returns true if this region's textual representation can be used as part of a larger expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
bool hasStackParametersStorage() const
StringRef getKindStr() const
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
bool hasStackStorage() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
ASTContext & getContext() const
std::string getDescriptiveName(bool UseQuotes=true) const
Get descriptive name for memory region.
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
virtual void dumpToStream(raw_ostream &os) const
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
virtual void printPrettyAsExpr(raw_ostream &os) const
Print the region as expression.
bool hasStackNonParametersStorage() const
std::string getString() const
Get a string representation of a region for debug use.
const RegionTy * getAs() const
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...
virtual MemRegionManager & getMemRegionManager() const =0
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
SourceRange sourceRange() const
Retrieve source range from memory region.
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
void Profile(llvm::FoldingSetNodeID &ID) const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl * getDecl() const override
void dumpToStream(raw_ostream &os) const override
The region associated with an ObjCStringLiteral.
void dumpToStream(raw_ostream &os) const override
ParamVarRegion - Represents a region for paremters.
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getOriginExpr() const
const ParmVarDecl * getDecl() const override
TODO: What does this return?
unsigned getIndex() const
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void dumpToStream(raw_ostream &os) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
InvalidationKinds
Describes different invalidation traits.
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Represent a region's offset within the top level base region.
static const int64_t Symbolic
CharUnits getOffset() const
void dumpToStream(raw_ostream &os) const
const MemRegion * getRegion() const
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
QualType getArrayIndexType() const
SymbolManager & getSymbolManager()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
void Profile(llvm::FoldingSetNodeID &ID) const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrameContext * getStackFrame() const
void Profile(llvm::FoldingSetNodeID &ID) const override
The region of the static variables within the current CodeTextRegion scope.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const CodeTextRegion * getCodeRegion() const
StringRegion - Region associated with a StringLiteral.
void dumpToStream(raw_ostream &os) const override
SubRegion - A region that subsets another larger region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
const MemRegion * superRegion
MemRegionManager & getMemRegionManager() const override
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.
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
static void ProfileRegion(llvm::FoldingSetNodeID &ID, SymbolRef sym, const MemRegion *superRegion)
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
void dumpToStream(raw_ostream &os) const override
const StackFrameContext * getStackFrame() const
It might return null.
Value representing integer constant.
Represents symbolic expression that isn't a location.
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.
Describes how types, statements, expressions, and declarations should be printed.