64#include "llvm/ADT/APSInt.h"
65#include "llvm/ADT/DenseMap.h"
66#include "llvm/ADT/ImmutableMap.h"
67#include "llvm/ADT/ImmutableSet.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/SmallVector.h"
70#include "llvm/Support/Casting.h"
71#include "llvm/Support/Compiler.h"
72#include "llvm/Support/DOTGraphTraits.h"
73#include "llvm/Support/ErrorHandling.h"
74#include "llvm/Support/GraphWriter.h"
75#include "llvm/Support/IOSandbox.h"
76#include "llvm/Support/TimeProfiler.h"
77#include "llvm/Support/raw_ostream.h"
90#define DEBUG_TYPE "ExprEngine"
93 "The # of times RemoveDeadBindings is called");
95 NumMaxBlockCountReached,
96 "The # of aborted paths due to reaching the maximum block count in "
97 "a top level function");
99 NumMaxBlockCountReachedInInlined,
100 "The # of aborted paths due to reaching the maximum block count in "
101 "an inlined function");
103 "The # of times we re-evaluated a call without inlining");
124class ConstructedObjectKey {
125 using ConstructedObjectKeyImpl =
126 std::pair<ConstructionContextItem, const StackFrame *>;
127 const ConstructedObjectKeyImpl Impl;
134 const ConstructionContextItem &getItem()
const {
return Impl.first; }
135 const StackFrame *getStackFrame()
const {
return Impl.second; }
137 ASTContext &getASTContext()
const {
138 return getStackFrame()->getDecl()->getASTContext();
141 void printJson(llvm::raw_ostream &Out, PrinterHelper *Helper,
142 PrintingPolicy &PP)
const {
143 const Stmt *S = getItem().getStmtOrNull();
144 const CXXCtorInitializer *I =
nullptr;
146 I = getItem().getCXXCtorInitializer();
149 Out <<
"\"stmt_id\": " << S->
getID(getASTContext());
151 Out <<
"\"init_id\": " << I->
getID(getASTContext());
154 Out <<
", \"kind\": \"" << getItem().getKindAsString()
155 <<
"\", \"argument_index\": ";
158 Out << getItem().getIndex();
163 Out <<
", \"pretty\": ";
172 void Profile(llvm::FoldingSetNodeID &ID)
const {
174 ID.AddPointer(Impl.second);
177 bool operator==(
const ConstructedObjectKey &RHS)
const {
178 return Impl == RHS.Impl;
181 bool operator<(
const ConstructedObjectKey &RHS)
const {
182 return Impl < RHS.Impl;
187typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
198typedef llvm::ImmutableMap<
199 std::pair<const CXXConstructExpr *, const StackFrame *>,
unsigned>
200 IndexOfElementToConstructMap;
202 IndexOfElementToConstructMap)
207typedef llvm::ImmutableMap<
208 std::pair<const CXXConstructExpr *, const StackFrame *>,
unsigned>
212typedef llvm::ImmutableMap<const StackFrame *, unsigned>
221static const char* TagProviderName =
"ExprEngine";
226 : CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
228 Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.
getGraph()),
229 StateMgr(
getContext(), mgr.getStoreManagerCreator(),
230 mgr.getConstraintManagerCreator(), G.getAllocator(), this),
232 svalBuilder(StateMgr.
getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
233 BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
234 HowToInline(HowToInlineIn) {
235 unsigned TrimInterval = mgr.
options.GraphTrimInterval;
236 if (TrimInterval != 0) {
238 G.enableNodeReclamation(TrimInterval);
254 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
258 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
263 const auto *BT = dyn_cast<BuiltinType>(
T);
264 if (!BT || !BT->isInteger())
267 const MemRegion *R = state->getRegion(PD, InitSF);
273 svalBuilder.makeZeroVal(
T),
274 svalBuilder.getConditionType());
276 std::optional<DefinedOrUnknownSVal> Constraint =
289 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
293 const MemRegion *R = state->getRegion(SelfD, InitSF);
296 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
298 state = state->assume(*LV,
true);
299 assert(state &&
"'self' cannot be null");
303 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
304 if (MD->isImplicitObjectMemberFunction()) {
311 SVal V = state->getSVal(L);
312 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
313 state = state->assume(*LV,
true);
314 assert(state &&
"'this' cannot be null");
326 const SubRegion **OutRegionWithAdjustments) {
332 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, SF);
337 if (OutRegionWithAdjustments)
338 *OutRegionWithAdjustments =
nullptr;
341 Result = InitWithAdjustments;
345 assert(!
isa<Loc>(InitValWithAdjustments) ||
347 Result->getType()->isMemberPointerType());
350 ProgramStateManager &StateMgr = State->getStateManager();
351 MemRegionManager &MRMgr = StateMgr.getRegionManager();
352 StoreManager &StoreMgr = StateMgr.getStoreManager();
375 SmallVector<const Expr *, 2> CommaLHSs;
376 SmallVector<SubobjectAdjustment, 2> Adjustments;
379 CommaLHSs, Adjustments);
386 const TypedValueRegion *TR =
nullptr;
387 if (
const auto *MT = dyn_cast<MaterializeTemporaryExpr>(
Result)) {
389 State = finishObjectConstruction(State, MT, SF);
390 State = State->BindExpr(
Result, SF, *
V);
392 }
else if (
const ValueDecl *VD = MT->getExtendingDecl()) {
398 TR = MRMgr.getCXXStaticLifetimeExtendedObjectRegion(
Init, VD);
400 TR = MRMgr.getCXXLifetimeExtendedObjectRegion(
Init, VD, SF);
404 TR = MRMgr.getCXXTempObjectRegion(
Init, SF);
407 TR = MRMgr.getCXXTempObjectRegion(
Init, SF);
410 SVal Reg = loc::MemRegionVal(TR);
414 for (
const SubobjectAdjustment &Adj : llvm::reverse(Adjustments)) {
426 nullptr,
nullptr,
nullptr);
439 SVal InitVal = State->getSVal(
Init, SF);
443 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, SF,
false);
447 if (InitValWithAdjustments.
isUnknown()) {
455 State->bindLoc(Reg.
castAs<Loc>(), InitValWithAdjustments, SF,
false);
457 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, SF,
false);
463 if (
Result->isGLValue()) {
464 State = State->BindExpr(
Result, SF, Reg);
466 State = State->BindExpr(
Result, SF, InitValWithAdjustments);
472 if (OutRegionWithAdjustments)
479 const CXXConstructExpr *E,
480 const StackFrame *SF,
unsigned Idx) {
481 auto Key = std::make_pair(E, SF);
483 assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
485 return State->set<IndexOfElementToConstruct>(Key, Idx);
488std::optional<unsigned>
491 const unsigned *
V = State->get<PendingInitLoop>({E, SF});
492 return V ? std::make_optional(*
V) : std::nullopt;
498 auto Key = std::make_pair(E, SF);
500 assert(E && State->contains<PendingInitLoop>(Key));
501 return State->remove<PendingInitLoop>(Key);
508 auto Key = std::make_pair(E, SF);
510 assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
512 return State->set<PendingInitLoop>(Key, Size);
517 const unsigned *
V = State->get<IndexOfElementToConstruct>({E, SF});
518 return V ? std::make_optional(*
V) : std::nullopt;
523 auto Key = std::make_pair(E, SF);
525 assert(E && State->contains<IndexOfElementToConstruct>(Key));
526 return State->remove<IndexOfElementToConstruct>(Key);
529std::optional<unsigned>
532 assert(SF &&
"StackFrame shouldn't be null!");
534 const unsigned *
V = State->get<PendingArrayDestruction>(SF);
535 return V ? std::make_optional(*
V) : std::nullopt;
541 assert(SF &&
"StackFrame shouldn't be null!");
542 return State->set<PendingArrayDestruction>(SF, Idx);
548 assert(SF &&
"StackFrame shouldn't be null!");
549 assert(State->contains<PendingArrayDestruction>(SF));
550 return State->remove<PendingArrayDestruction>(SF);
557 ConstructedObjectKey Key(Item, SF);
561 if (
auto DS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
562 if (
auto VD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
563 Init = VD->getInit();
566 if (
auto LE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
575 if (
const auto *AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
584 assert((!State->get<ObjectsUnderConstruction>(Key) ||
585 Key.getItem().getKind() ==
587 State->contains<IndexOfElementToConstruct>(
588 {dyn_cast_or_null<CXXConstructExpr>(Init), SF})) &&
589 "The object is already marked as `UnderConstruction`, when it's not "
591 return State->set<ObjectsUnderConstruction>(Key,
V);
598 ConstructedObjectKey Key(Item, SF);
599 const SVal *
V = State->get<ObjectsUnderConstruction>(Key);
600 return V ? std::make_optional(*
V) : std::nullopt;
607 ConstructedObjectKey Key(Item, SF);
608 assert(State->contains<ObjectsUnderConstruction>(Key));
609 return State->remove<ObjectsUnderConstruction>(Key);
615 ConstructedObjectKey Key({BTE,
true}, SF);
618 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
623 const CXXBindTemporaryExpr *BTE,
624 const StackFrame *SF) {
625 ConstructedObjectKey Key({BTE,
true}, SF);
626 assert(State->contains<ObjectsUnderConstruction>(Key));
627 return State->remove<ObjectsUnderConstruction>(Key);
631 const CXXBindTemporaryExpr *BTE,
632 const StackFrame *SF) {
633 ConstructedObjectKey Key({BTE,
true}, SF);
634 return State->contains<ObjectsUnderConstruction>(Key);
638 const StackFrame *FromSF,
639 const StackFrame *ToSF) {
640 const StackFrame *SF = FromSF;
642 assert(SF &&
"ToSF must be a parent of FromSF!");
643 for (
auto I : State->get<ObjectsUnderConstruction>())
644 if (I.first.getStackFrame() == SF)
659 SVal cond,
bool assumption) {
668 state, invalidated, Explicits, Regions, SF,
Call);
674 unsigned int Space = 0,
bool IsDot =
false) {
679 bool HasItem =
false;
682 const ConstructedObjectKey *LastKey =
nullptr;
683 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
684 const ConstructedObjectKey &Key = I.first;
685 if (Key.getStackFrame() != SF)
696 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
697 const ConstructedObjectKey &Key = I.first;
699 if (Key.getStackFrame() != SF)
702 Indent(Out, Space, IsDot) <<
"{ ";
703 Key.printJson(Out,
nullptr, PP);
704 Out <<
", \"value\": \"" <<
Value <<
"\" }";
712 Indent(Out, --Space, IsDot) <<
']';
720 const StackFrame *SF,
unsigned int Space = 0,
bool IsDot =
false) {
721 using KeyT = std::pair<const Expr *, const StackFrame *>;
727 bool HasItem =
false;
731 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
732 const KeyT &Key = I.first;
733 if (Key.second != SF)
744 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
745 const KeyT &Key = I.first;
746 unsigned Value = I.second;
747 if (Key.second != SF)
750 Indent(Out, Space, IsDot) <<
"{ ";
753 const Expr *E = Key.first;
754 Out <<
"\"stmt_id\": " << E->
getID(Context);
757 Out <<
", \"kind\": null";
760 Out <<
", \"pretty\": ";
766 Out <<
", \"value\": \"Current index: " <<
Value - 1 <<
"\" }";
774 Indent(Out, --Space, IsDot) <<
']';
782 unsigned int Space = 0,
783 bool IsDot =
false) {
784 using KeyT = std::pair<const CXXConstructExpr *, const StackFrame *>;
790 bool HasItem =
false;
794 for (
const auto &I : State->get<PendingInitLoop>()) {
795 const KeyT &Key = I.first;
796 if (Key.second != SF)
807 for (
const auto &I : State->get<PendingInitLoop>()) {
808 const KeyT &Key = I.first;
809 unsigned Value = I.second;
810 if (Key.second != SF)
813 Indent(Out, Space, IsDot) <<
"{ ";
816 Out <<
"\"stmt_id\": " << E->
getID(Context);
818 Out <<
", \"kind\": null";
819 Out <<
", \"pretty\": ";
825 Out <<
", \"value\": \"Flattened size: " <<
Value <<
"\"}";
833 Indent(Out, --Space, IsDot) <<
']';
842 unsigned int Space = 0,
bool IsDot =
false) {
846 bool HasItem =
false;
849 KeyT LastKey =
nullptr;
850 for (
const auto &I : State->get<PendingArrayDestruction>()) {
851 const KeyT &Key = I.first;
863 for (
const auto &I : State->get<PendingArrayDestruction>()) {
864 const KeyT &Key = I.first;
868 Indent(Out, Space, IsDot) <<
"{ ";
870 Out <<
"\"stmt_id\": null";
871 Out <<
", \"kind\": null";
872 Out <<
", \"pretty\": \"Current index: \"";
873 Out <<
", \"value\": \"" << I.second <<
"\" }";
881 Indent(Out, --Space, IsDot) <<
']';
895template <
typename Trait,
typename Printer,
typename... Args>
898 const char *NL,
unsigned int Space,
bool IsDot,
899 const char *jsonPropertyName, Printer printer, Args &&...args) {
903 unsigned int,
bool, Args &&...);
907 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
908 "Printer is not a function!");
909 static_assert(std::is_convertible_v<Printer, RequiredType>,
910 "Printer doesn't have the required type!");
912 if (SF && !State->get<Trait>().isEmpty()) {
913 Indent(Out, Space, IsDot) <<
'\"' << jsonPropertyName <<
"\": ";
917 printer(Out, State, NL, SF, Space, IsDot, std::forward<Args>(args)...);
921 Indent(Out, Space, IsDot) <<
"]," << NL;
927 unsigned int Space,
bool IsDot)
const {
930 Out, State, SF, NL, Space, IsDot,
"constructing_objects",
933 Out, State, SF, NL, Space, IsDot,
"index_of_element",
936 Out, State, SF, NL, Space, IsDot,
"pending_init_loops",
939 Out, State, SF, NL, Space, IsDot,
"pending_destructors",
954 currStmtIdx = StmtIdx;
1019 llvm::TimeTraceScope TimeScope(
"ExprEngine::removeDead");
1022 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1023 assert(SF &&
"Must pass the current (or expiring) StackFrame");
1025 if (!DiagnosticStmt) {
1026 DiagnosticStmt = ReferenceStmt;
1027 assert(DiagnosticStmt &&
"Required for clearing a StackFrame");
1030 NumRemoveDeadBindings++;
1036 if (!ReferenceStmt) {
1038 "Use PostStmtPurgeDeadSymbolsKind for clearing a StackFrame");
1044 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1045 if (
SymbolRef Sym = I.second.getAsSymbol())
1047 if (
const MemRegion *MR = I.second.getAsRegion())
1056 CleanedState = StateMgr.removeDeadBindingsFromEnvironmentAndStore(
1057 CleanedState, SF, SymReaper);
1064 DiagnosticStmt, *
this, K);
1074 for (
const auto I : CheckedSet) {
1081 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->
getState()) &&
1082 "Checkers are not allowed to modify the Environment as a part of "
1083 "checkDeadSymbols processing.");
1084 assert(StateMgr.haveEqualStores(CheckerState, Pred->
getState()) &&
1085 "Checkers are not allowed to modify the Store as a part of "
1086 "checkDeadSymbols processing.");
1091 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1094 Out.insert(Engine.makeNode(L, CleanedCheckerSt, I));
1104enum class VisitKind {
1118 case Stmt::CXXDependentScopeMemberExprClass:
1119 case Stmt::CXXReflectExprClass:
1120 case Stmt::CXXTryStmtClass:
1121 case Stmt::CXXTypeidExprClass:
1122 case Stmt::CXXUuidofExprClass:
1123 case Stmt::CXXFoldExprClass:
1124 case Stmt::MSPropertyRefExprClass:
1125 case Stmt::MSPropertySubscriptExprClass:
1126 case Stmt::CXXUnresolvedConstructExprClass:
1127 case Stmt::DependentScopeDeclRefExprClass:
1128 case Stmt::ArrayTypeTraitExprClass:
1129 case Stmt::ExpressionTraitExprClass:
1130 case Stmt::UnresolvedLookupExprClass:
1131 case Stmt::UnresolvedMemberExprClass:
1132 case Stmt::DependentTemplateIdExprClass:
1133 case Stmt::RecoveryExprClass:
1134 case Stmt::CXXNoexceptExprClass:
1135 case Stmt::PackExpansionExprClass:
1136 case Stmt::PackIndexingExprClass:
1137 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1138 case Stmt::FunctionParmPackExprClass:
1139 case Stmt::CoroutineBodyStmtClass:
1140 case Stmt::CoawaitExprClass:
1141 case Stmt::DependentCoawaitExprClass:
1142 case Stmt::CoreturnStmtClass:
1143 case Stmt::CoyieldExprClass:
1144 case Stmt::SEHTryStmtClass:
1145 case Stmt::SEHExceptStmtClass:
1146 case Stmt::SEHLeaveStmtClass:
1147 case Stmt::SEHFinallyStmtClass:
1148 case Stmt::CXXExpansionStmtPatternClass:
1149 case Stmt::CXXExpansionStmtInstantiationClass:
1150 case Stmt::CXXExpansionSelectExprClass:
1151 case Stmt::OMPCanonicalLoopClass:
1152 case Stmt::OMPParallelDirectiveClass:
1153 case Stmt::OMPSimdDirectiveClass:
1154 case Stmt::OMPForDirectiveClass:
1155 case Stmt::OMPForSimdDirectiveClass:
1156 case Stmt::OMPSectionsDirectiveClass:
1157 case Stmt::OMPSectionDirectiveClass:
1158 case Stmt::OMPScopeDirectiveClass:
1159 case Stmt::OMPSingleDirectiveClass:
1160 case Stmt::OMPMasterDirectiveClass:
1161 case Stmt::OMPCriticalDirectiveClass:
1162 case Stmt::OMPParallelForDirectiveClass:
1163 case Stmt::OMPParallelForSimdDirectiveClass:
1164 case Stmt::OMPParallelSectionsDirectiveClass:
1165 case Stmt::OMPParallelMasterDirectiveClass:
1166 case Stmt::OMPParallelMaskedDirectiveClass:
1167 case Stmt::OMPTaskDirectiveClass:
1168 case Stmt::OMPTaskyieldDirectiveClass:
1169 case Stmt::OMPBarrierDirectiveClass:
1170 case Stmt::OMPTaskwaitDirectiveClass:
1171 case Stmt::OMPErrorDirectiveClass:
1172 case Stmt::OMPTaskgroupDirectiveClass:
1173 case Stmt::OMPFlushDirectiveClass:
1174 case Stmt::OMPDepobjDirectiveClass:
1175 case Stmt::OMPScanDirectiveClass:
1176 case Stmt::OMPOrderedStandaloneDirectiveClass:
1177 case Stmt::OMPOrderedBlockAssocDirectiveClass:
1178 case Stmt::OMPAtomicDirectiveClass:
1179 case Stmt::OMPAssumeDirectiveClass:
1180 case Stmt::OMPTargetDirectiveClass:
1181 case Stmt::OMPTargetDataDirectiveClass:
1182 case Stmt::OMPTargetEnterDataDirectiveClass:
1183 case Stmt::OMPTargetExitDataDirectiveClass:
1184 case Stmt::OMPTargetParallelDirectiveClass:
1185 case Stmt::OMPTargetParallelForDirectiveClass:
1186 case Stmt::OMPTargetUpdateDirectiveClass:
1187 case Stmt::OMPTeamsDirectiveClass:
1188 case Stmt::OMPCancellationPointDirectiveClass:
1189 case Stmt::OMPCancelDirectiveClass:
1190 case Stmt::OMPTaskLoopDirectiveClass:
1191 case Stmt::OMPTaskLoopSimdDirectiveClass:
1192 case Stmt::OMPMasterTaskLoopDirectiveClass:
1193 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1194 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1195 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1196 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1197 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1198 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1199 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1200 case Stmt::OMPDistributeDirectiveClass:
1201 case Stmt::OMPDistributeParallelForDirectiveClass:
1202 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1203 case Stmt::OMPDistributeSimdDirectiveClass:
1204 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1205 case Stmt::OMPTargetSimdDirectiveClass:
1206 case Stmt::OMPTeamsDistributeDirectiveClass:
1207 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1208 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1209 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1210 case Stmt::OMPTargetTeamsDirectiveClass:
1211 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1212 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1213 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1214 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1215 case Stmt::OMPReverseDirectiveClass:
1216 case Stmt::OMPStripeDirectiveClass:
1217 case Stmt::OMPTileDirectiveClass:
1218 case Stmt::OMPInterchangeDirectiveClass:
1219 case Stmt::OMPSplitDirectiveClass:
1220 case Stmt::OMPFuseDirectiveClass:
1221 case Stmt::OMPInteropDirectiveClass:
1222 case Stmt::OMPDispatchDirectiveClass:
1223 case Stmt::OMPMaskedDirectiveClass:
1224 case Stmt::OMPGenericLoopDirectiveClass:
1225 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1226 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1227 case Stmt::OMPParallelGenericLoopDirectiveClass:
1228 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1229 case Stmt::CapturedStmtClass:
1230 case Stmt::SYCLKernelCallStmtClass:
1231 case Stmt::UnresolvedSYCLKernelCallStmtClass:
1232 case Stmt::OpenACCComputeConstructClass:
1233 case Stmt::OpenACCLoopConstructClass:
1234 case Stmt::OpenACCCombinedConstructClass:
1235 case Stmt::OpenACCDataConstructClass:
1236 case Stmt::OpenACCEnterDataConstructClass:
1237 case Stmt::OpenACCExitDataConstructClass:
1238 case Stmt::OpenACCHostDataConstructClass:
1239 case Stmt::OpenACCWaitConstructClass:
1240 case Stmt::OpenACCCacheConstructClass:
1241 case Stmt::OpenACCInitConstructClass:
1242 case Stmt::OpenACCShutdownConstructClass:
1243 case Stmt::OpenACCSetConstructClass:
1244 case Stmt::OpenACCUpdateConstructClass:
1245 case Stmt::OpenACCAtomicConstructClass:
1246 case Stmt::OMPUnrollDirectiveClass:
1247 case Stmt::OMPMetaDirectiveClass:
1248 case Stmt::HLSLOutArgExprClass:
1252 case Stmt::GNUNullExprClass:
1256 case Stmt::ObjCAtSynchronizedStmtClass:
1257 return K == VisitKind::Pre;
1260 case Expr::ConstantExprClass:
1261 case Stmt::ExprWithCleanupsClass:
1265 case Stmt::MSAsmStmtClass:
1269 case Stmt::BlockExprClass:
1270 return K == VisitKind::Post;
1276 case Stmt::LambdaExprClass:
1281 case Stmt::BinaryOperatorClass:
1286 case Stmt::CXXOperatorCallExprClass:
1287 case Stmt::CallExprClass:
1288 case Stmt::CXXMemberCallExprClass:
1289 case Stmt::UserDefinedLiteralClass:
1293 case Stmt::CXXCatchStmtClass:
1298 case Stmt::CXXTemporaryObjectExprClass:
1299 case Stmt::CXXConstructExprClass:
1304 case Stmt::CXXInheritedCtorInitExprClass:
1308 case Stmt::ChooseExprClass:
1313 case Stmt::CompoundAssignOperatorClass:
1317 case Stmt::CompoundLiteralExprClass:
1321 case Stmt::BinaryConditionalOperatorClass:
1322 case Stmt::ConditionalOperatorClass:
1326 case Stmt::CXXThisExprClass:
1330 case Stmt::DeclRefExprClass:
1334 case Stmt::DeclStmtClass:
1339 case Stmt::InitListExprClass:
1340 case Expr::CXXParenListInitExprClass:
1344 case Stmt::ObjCIvarRefExprClass:
1345 return K == VisitKind::Post;
1348 case Stmt::ObjCForCollectionStmtClass:
1349 return K == VisitKind::Post;
1352 case Stmt::ObjCMessageExprClass:
1356 case Stmt::ObjCAtThrowStmtClass:
1357 case Stmt::CXXThrowExprClass:
1361 case Stmt::ReturnStmtClass:
1362 return K == VisitKind::Pre;
1365 case Stmt::StmtExprClass:
1369 case Stmt::UnaryOperatorClass:
1373 case Stmt::PseudoObjectExprClass:
1377 case Expr::ObjCIndirectCopyRestoreExprClass:
1384 G.reclaimRecentlyAllocatedNodes();
1388 "Error evaluating statement");
1395 CleanedStates.
insert(Pred);
1402 PreVisited.
insert(CleanedStates);
1405 for (
const auto I : PreVisited) {
1407 Visit(currStmt, I, Tmp);
1416 PostVisited.
insert(Visited);
1419 Engine.enqueueStmtNodes(PostVisited,
getCurrBlock(), currStmtIdx);
1425 "Error evaluating end of the loop");
1428 if(AMgr.options.ShouldUnrollLoops)
1432 if (
ExplodedNode *N = Engine.makeNode(PP, NewState, Pred))
1433 Engine.enqueueStmtNode(N,
getCurrBlock(), currStmtIdx);
1440 "Error evaluating end of a lifetime");
1446 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1457 "Error evaluating initializer");
1463 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(
decl, SF));
1475 State = finishObjectConstruction(State, BMI, SF);
1477 Tmp.
insert(Engine.makeNode(PS, State, Pred));
1485 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1489 if (Field->getType()->isArrayType()) {
1493 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1496 InitVal = State->getSVal(
Init, SF);
1505 InitVal = State->getSVal(BMI->
getInit(), SF);
1509 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1517 SVal InitVal = State->getSVal(
Init, SF);
1518 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1533 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1536std::pair<ProgramStateRef, uint64_t>
1537ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRef State,
1541 SVal *ElementCountVal) {
1542 assert(Region !=
nullptr &&
"Not-null region expected");
1545 while (
const auto *NTy = dyn_cast<ArrayType>(Ty))
1546 Ty = NTy->getElementType().getDesugaredType(
getContext());
1550 if (ElementCountVal)
1551 *ElementCountVal = ElementCount;
1559 if (!ElementCount.isConstant())
1562 Idx = ElementCount.getAsInteger()->getLimitedValue();
1570 return {setPendingArrayDestruction(State, SF, Idx), Idx};
1593 llvm_unreachable(
"Unexpected dtor kind.");
1597 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1608 if (Opts.MayInlineCXXAllocator)
1616 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1622 const auto *DtorDecl = Dtor.getDestructorDecl(
getContext());
1633 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1648 std::tie(state, Idx) = prepareStateForArrayDestruction(
1649 state, Region, varType, SF, &ElementCount);
1651 if (ElementCount.isConstant()) {
1652 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1653 assert(ArrayLength &&
1654 "An automatic dtor for a 0 length array shouldn't be triggered!");
1659 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1660 "which shouldn't be in the CFG.");
1663 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1675 "Prepare for object destruction");
1678 Pred = Engine.makeNode(PP, state, Pred);
1684 false, Pred, Dst, CallOpts);
1695 SVal ArgVal = State->getSVal(Arg, SF);
1699 if (State->isNull(ArgVal).isConstrainedTrue()) {
1709 auto getDtorDecl = [](
const QualType &DTy) {
1721 while (
const auto *AT =
getContext().getAsArrayType(DTy))
1722 DTy = AT->getElementType();
1726 std::tie(State, Idx) =
1727 prepareStateForArrayDestruction(State, ArgR, DTy, SF, &ElementCount);
1731 if (ElementCount.isConstant() &&
1732 ElementCount.getAsInteger()->getLimitedValue() == 0) {
1735 "ExprEngine",
"Skipping 0 length array delete destruction");
1742 ArgR = State->getLValue(DTy, svalBuilder.makeArrayIndex(Idx), ArgVal)
1748 "Prepare for object destruction");
1751 Pred = Engine.makeNode(PP, State, Pred);
1775 true, Pred, Dst, CallOpts);
1788 Loc ThisLoc = State->getSVal(ThisStorageLoc).
castAs<
Loc>();
1789 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1794 std::tie(State, Idx) = prepareStateForArrayDestruction(
1795 State, FieldVal.getAsRegion(),
T, SF, &ElementCount);
1797 if (ElementCount.isConstant()) {
1798 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1799 assert(ArrayLength &&
1800 "A member dtor for a 0 length array shouldn't be triggered!");
1805 "ExprEngine",
"Skipping member 0 length array destruction, which "
1806 "shouldn't be in the CFG.");
1809 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1820 "Prepare for object destruction");
1823 Pred = Engine.makeNode(PP, State, Pred);
1829 false, Pred, Dst, CallOpts);
1844 State = finishObjectConstruction(State, BTE, SF);
1845 MR =
V->getAsRegion();
1850 if (isDestructorElided(State, BTE, SF)) {
1851 State = cleanupElidedDestructor(State, BTE, SF);
1854 Dst.
insert(Engine.makeNode(PP, State, Pred));
1858 ExplodedNode *CleanPred = Engine.makePostStmtNode(BTE, State, Pred);
1888 T = AT->getElementType();
1899 false, CleanPred, Dst, CallOpts);
1911 if (
const CFGBlock *DstBlock = Obj ? DstT : DstF) {
1913 Dst.
insert(Engine.makeNode(BE, State, Pred));
1936 State = addObjectUnderConstruction(State, BTE, SF,
UnknownVal());
1938 Dst.
insert(Engine.makePostStmtNode(BTE, State, Pred));
1945 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1950 : Symbols(Symbols) {}
1954 bool VisitSymbol(
SymbolRef Sym)
override {
1955 Symbols.insert(Sym);
1960 CollectReachableSymbolsCallback CallBack(Symbols);
1962 State->scanReachableSymbols(
V, CallBack);
1965 State, CallBack.getSymbols(),
Call, K,
nullptr);
1977 case Stmt::CXXDependentScopeMemberExprClass:
1978 case Stmt::CXXReflectExprClass:
1979 case Stmt::CXXTryStmtClass:
1980 case Stmt::CXXTypeidExprClass:
1981 case Stmt::CXXUuidofExprClass:
1982 case Stmt::CXXFoldExprClass:
1983 case Stmt::MSPropertyRefExprClass:
1984 case Stmt::MSPropertySubscriptExprClass:
1985 case Stmt::CXXUnresolvedConstructExprClass:
1986 case Stmt::DependentScopeDeclRefExprClass:
1987 case Stmt::ArrayTypeTraitExprClass:
1988 case Stmt::ExpressionTraitExprClass:
1989 case Stmt::UnresolvedLookupExprClass:
1990 case Stmt::UnresolvedMemberExprClass:
1991 case Stmt::DependentTemplateIdExprClass:
1992 case Stmt::RecoveryExprClass:
1993 case Stmt::CXXNoexceptExprClass:
1994 case Stmt::PackExpansionExprClass:
1995 case Stmt::PackIndexingExprClass:
1996 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1997 case Stmt::FunctionParmPackExprClass:
1998 case Stmt::CoroutineBodyStmtClass:
1999 case Stmt::CoawaitExprClass:
2000 case Stmt::DependentCoawaitExprClass:
2001 case Stmt::CoreturnStmtClass:
2002 case Stmt::CoyieldExprClass:
2003 case Stmt::SEHTryStmtClass:
2004 case Stmt::SEHExceptStmtClass:
2005 case Stmt::SEHLeaveStmtClass:
2006 case Stmt::SEHFinallyStmtClass:
2007 case Stmt::CXXExpansionStmtPatternClass:
2008 case Stmt::CXXExpansionStmtInstantiationClass:
2009 case Stmt::CXXExpansionSelectExprClass:
2010 case Stmt::OMPCanonicalLoopClass:
2011 case Stmt::OMPParallelDirectiveClass:
2012 case Stmt::OMPSimdDirectiveClass:
2013 case Stmt::OMPForDirectiveClass:
2014 case Stmt::OMPForSimdDirectiveClass:
2015 case Stmt::OMPSectionsDirectiveClass:
2016 case Stmt::OMPSectionDirectiveClass:
2017 case Stmt::OMPScopeDirectiveClass:
2018 case Stmt::OMPSingleDirectiveClass:
2019 case Stmt::OMPMasterDirectiveClass:
2020 case Stmt::OMPCriticalDirectiveClass:
2021 case Stmt::OMPParallelForDirectiveClass:
2022 case Stmt::OMPParallelForSimdDirectiveClass:
2023 case Stmt::OMPParallelSectionsDirectiveClass:
2024 case Stmt::OMPParallelMasterDirectiveClass:
2025 case Stmt::OMPParallelMaskedDirectiveClass:
2026 case Stmt::OMPTaskDirectiveClass:
2027 case Stmt::OMPTaskyieldDirectiveClass:
2028 case Stmt::OMPBarrierDirectiveClass:
2029 case Stmt::OMPTaskwaitDirectiveClass:
2030 case Stmt::OMPErrorDirectiveClass:
2031 case Stmt::OMPTaskgroupDirectiveClass:
2032 case Stmt::OMPFlushDirectiveClass:
2033 case Stmt::OMPDepobjDirectiveClass:
2034 case Stmt::OMPScanDirectiveClass:
2035 case Stmt::OMPOrderedStandaloneDirectiveClass:
2036 case Stmt::OMPOrderedBlockAssocDirectiveClass:
2037 case Stmt::OMPAtomicDirectiveClass:
2038 case Stmt::OMPAssumeDirectiveClass:
2039 case Stmt::OMPTargetDirectiveClass:
2040 case Stmt::OMPTargetDataDirectiveClass:
2041 case Stmt::OMPTargetEnterDataDirectiveClass:
2042 case Stmt::OMPTargetExitDataDirectiveClass:
2043 case Stmt::OMPTargetParallelDirectiveClass:
2044 case Stmt::OMPTargetParallelForDirectiveClass:
2045 case Stmt::OMPTargetUpdateDirectiveClass:
2046 case Stmt::OMPTeamsDirectiveClass:
2047 case Stmt::OMPCancellationPointDirectiveClass:
2048 case Stmt::OMPCancelDirectiveClass:
2049 case Stmt::OMPTaskLoopDirectiveClass:
2050 case Stmt::OMPTaskLoopSimdDirectiveClass:
2051 case Stmt::OMPMasterTaskLoopDirectiveClass:
2052 case Stmt::OMPMaskedTaskLoopDirectiveClass:
2053 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
2054 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
2055 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
2056 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
2057 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
2058 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
2059 case Stmt::OMPDistributeDirectiveClass:
2060 case Stmt::OMPDistributeParallelForDirectiveClass:
2061 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
2062 case Stmt::OMPDistributeSimdDirectiveClass:
2063 case Stmt::OMPTargetParallelForSimdDirectiveClass:
2064 case Stmt::OMPTargetSimdDirectiveClass:
2065 case Stmt::OMPTeamsDistributeDirectiveClass:
2066 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
2067 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
2068 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
2069 case Stmt::OMPTargetTeamsDirectiveClass:
2070 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
2071 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
2072 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
2073 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
2074 case Stmt::OMPReverseDirectiveClass:
2075 case Stmt::OMPStripeDirectiveClass:
2076 case Stmt::OMPTileDirectiveClass:
2077 case Stmt::OMPInterchangeDirectiveClass:
2078 case Stmt::OMPFlattenDirectiveClass:
2079 case Stmt::OMPSplitDirectiveClass:
2080 case Stmt::OMPFuseDirectiveClass:
2081 case Stmt::OMPInteropDirectiveClass:
2082 case Stmt::OMPDispatchDirectiveClass:
2083 case Stmt::OMPMaskedDirectiveClass:
2084 case Stmt::OMPGenericLoopDirectiveClass:
2085 case Stmt::OMPTeamsGenericLoopDirectiveClass:
2086 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
2087 case Stmt::OMPParallelGenericLoopDirectiveClass:
2088 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
2089 case Stmt::CapturedStmtClass:
2090 case Stmt::SYCLKernelCallStmtClass:
2091 case Stmt::UnresolvedSYCLKernelCallStmtClass:
2092 case Stmt::OpenACCComputeConstructClass:
2093 case Stmt::OpenACCLoopConstructClass:
2094 case Stmt::OpenACCCombinedConstructClass:
2095 case Stmt::OpenACCDataConstructClass:
2096 case Stmt::OpenACCEnterDataConstructClass:
2097 case Stmt::OpenACCExitDataConstructClass:
2098 case Stmt::OpenACCHostDataConstructClass:
2099 case Stmt::OpenACCWaitConstructClass:
2100 case Stmt::OpenACCCacheConstructClass:
2101 case Stmt::OpenACCInitConstructClass:
2102 case Stmt::OpenACCShutdownConstructClass:
2103 case Stmt::OpenACCSetConstructClass:
2104 case Stmt::OpenACCUpdateConstructClass:
2105 case Stmt::OpenACCAtomicConstructClass:
2106 case Stmt::OMPUnrollDirectiveClass:
2107 case Stmt::OMPMetaDirectiveClass:
2108 case Stmt::HLSLOutArgExprClass: {
2115 case Stmt::ParenExprClass:
2116 llvm_unreachable(
"ParenExprs already handled.");
2117 case Stmt::GenericSelectionExprClass:
2118 llvm_unreachable(
"GenericSelectionExprs already handled.");
2121 case Stmt::BreakStmtClass:
2122 case Stmt::CaseStmtClass:
2123 case Stmt::CompoundStmtClass:
2124 case Stmt::ContinueStmtClass:
2125 case Stmt::CXXForRangeStmtClass:
2126 case Stmt::DefaultStmtClass:
2127 case Stmt::DoStmtClass:
2128 case Stmt::ForStmtClass:
2129 case Stmt::GotoStmtClass:
2130 case Stmt::IfStmtClass:
2131 case Stmt::IndirectGotoStmtClass:
2132 case Stmt::LabelStmtClass:
2134 case Stmt::NullStmtClass:
2135 case Stmt::SwitchStmtClass:
2136 case Stmt::WhileStmtClass:
2137 case Stmt::DeferStmtClass:
2138 case Expr::MSDependentExistsStmtClass:
2139 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
2140 case Stmt::ImplicitValueInitExprClass:
2144 llvm_unreachable(
"Should be pruned from CFG");
2146 case Stmt::ObjCSubscriptRefExprClass:
2147 case Stmt::ObjCPropertyRefExprClass:
2148 llvm_unreachable(
"These are handled by PseudoObjectExpr");
2150 case Stmt::GNUNullExprClass: {
2152 SVal Val = svalBuilder.makeIntValWithWidth(
getContext().VoidPtrTy, 0);
2157 case Stmt::ObjCAtSynchronizedStmtClass: {
2162 case Expr::ConstantExprClass:
2163 case Stmt::ExprWithCleanupsClass:
2168 case Stmt::CXXBindTemporaryExprClass:
2172 case Stmt::ArrayInitLoopExprClass:
2176 case Stmt::DesignatedInitExprClass:
2177 case Stmt::DesignatedInitUpdateExprClass:
2178 case Stmt::ArrayInitIndexExprClass:
2179 case Stmt::ExtVectorElementExprClass:
2180 case Stmt::MatrixElementExprClass:
2181 case Stmt::ImaginaryLiteralClass:
2182 case Stmt::ObjCAtCatchStmtClass:
2183 case Stmt::ObjCAtFinallyStmtClass:
2184 case Stmt::ObjCAtTryStmtClass:
2185 case Stmt::ObjCAutoreleasePoolStmtClass:
2186 case Stmt::ObjCEncodeExprClass:
2187 case Stmt::ObjCIsaExprClass:
2188 case Stmt::ObjCProtocolExprClass:
2189 case Stmt::ObjCSelectorExprClass:
2190 case Stmt::ParenListExprClass:
2191 case Stmt::ShuffleVectorExprClass:
2192 case Stmt::ConvertVectorExprClass:
2193 case Stmt::VAArgExprClass:
2194 case Stmt::CUDAKernelCallExprClass:
2195 case Stmt::OpaqueValueExprClass:
2196 case Stmt::AsTypeExprClass:
2197 case Stmt::ConceptSpecializationExprClass:
2198 case Stmt::CXXRewrittenBinaryOperatorClass:
2199 case Stmt::RequiresExprClass:
2200 case Stmt::EmbedExprClass:
2205 case Stmt::PredefinedExprClass:
2206 case Stmt::AddrLabelExprClass:
2207 case Stmt::IntegerLiteralClass:
2208 case Stmt::FixedPointLiteralClass:
2209 case Stmt::CharacterLiteralClass:
2210 case Stmt::CXXScalarValueInitExprClass:
2211 case Stmt::CXXBoolLiteralExprClass:
2212 case Stmt::ObjCBoolLiteralExprClass:
2213 case Stmt::ObjCAvailabilityCheckExprClass:
2214 case Stmt::FloatingLiteralClass:
2215 case Stmt::NoInitExprClass:
2216 case Stmt::SizeOfPackExprClass:
2217 case Stmt::StringLiteralClass:
2218 case Stmt::SourceLocExprClass:
2219 case Stmt::ObjCStringLiteralClass:
2220 case Stmt::CXXPseudoDestructorExprClass:
2221 case Stmt::SubstNonTypeTemplateParmExprClass:
2222 case Stmt::CXXNullPtrLiteralExprClass:
2223 case Stmt::ArraySectionExprClass:
2224 case Stmt::OMPArrayShapingExprClass:
2225 case Stmt::OMPIteratorExprClass:
2226 case Stmt::SYCLUniqueStableNameExprClass:
2227 case Stmt::OpenACCAsteriskSizeExprClass:
2228 case Stmt::TypeTraitExprClass: {
2233 case Stmt::AttributedStmtClass:
2237 case Stmt::CXXDefaultArgExprClass:
2238 case Stmt::CXXDefaultInitExprClass: {
2241 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
2242 ArgE = DefE->getExpr();
2243 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
2244 ArgE = DefE->getExpr();
2246 llvm_unreachable(
"unknown constant wrapper kind");
2248 bool IsTemporary =
false;
2249 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
2250 ArgE = MTE->getSubExpr();
2254 std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
2260 State = State->BindExpr(
cast<Expr>(S), SF, *ConstantVal);
2262 State = createTemporaryRegionIfNeeded(State, SF,
cast<Expr>(S),
2264 Dst.
insert(Engine.makePostStmtNode(S, State, Pred));
2270 case Stmt::CXXStdInitializerListExprClass:
2271 case Expr::ObjCArrayLiteralClass:
2272 case Expr::ObjCDictionaryLiteralClass:
2273 case Expr::ObjCBoxedExprClass: {
2275 QualType resultType = Ex->getType();
2278 SVal result = svalBuilder.conjureSymbolVal(
2287 for (
auto Child : Ex->children()) {
2289 const auto *ChildExpr = dyn_cast<Expr>(Child);
2290 SVal Val = ChildExpr ? State->getSVal(ChildExpr, SF) :
UnknownVal();
2294 Dst.
insert(Engine.makePostStmtNode(S, State, Pred));
2298 case Stmt::ArraySubscriptExprClass:
2302 case Stmt::MatrixSingleSubscriptExprClass:
2304 "Support for MatrixSingleSubscriptExprClass is not implemented.");
2307 case Stmt::MatrixSubscriptExprClass:
2308 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2311 case Stmt::GCCAsmStmtClass:
2315 case Stmt::MSAsmStmtClass:
2319 case Stmt::BlockExprClass:
2323 case Stmt::LambdaExprClass:
2327 case Stmt::BinaryOperatorClass: {
2329 if (B->isLogicalOp()) {
2332 }
else if (B->getOpcode() == BO_Comma) {
2335 Dst.
insert(Engine.makeNodeWithBinding(Pred, B, Val));
2339 if (AMgr.options.ShouldEagerlyAssume &&
2340 (B->isRelationalOp() || B->isEqualityOp())) {
2351 case Stmt::CXXOperatorCallExprClass:
2352 case Stmt::CallExprClass:
2353 case Stmt::CXXMemberCallExprClass:
2354 case Stmt::UserDefinedLiteralClass:
2358 case Stmt::CXXCatchStmtClass:
2362 case Stmt::CXXTemporaryObjectExprClass:
2363 case Stmt::CXXConstructExprClass:
2367 case Stmt::CXXInheritedCtorInitExprClass:
2372 case Stmt::CXXNewExprClass:
2376 case Stmt::CXXDeleteExprClass:
2382 case Stmt::ChooseExprClass: {
2388 case Stmt::CompoundAssignOperatorClass:
2392 case Stmt::CompoundLiteralExprClass:
2396 case Stmt::BinaryConditionalOperatorClass:
2397 case Stmt::ConditionalOperatorClass: {
2403 case Stmt::CXXThisExprClass:
2407 case Stmt::DeclRefExprClass: {
2413 case Stmt::DeclStmtClass:
2417 case Stmt::ImplicitCastExprClass:
2418 case Stmt::CStyleCastExprClass:
2419 case Stmt::CXXStaticCastExprClass:
2420 case Stmt::CXXDynamicCastExprClass:
2421 case Stmt::CXXReinterpretCastExprClass:
2422 case Stmt::CXXConstCastExprClass:
2423 case Stmt::CXXFunctionalCastExprClass:
2424 case Stmt::BuiltinBitCastExprClass:
2425 case Stmt::ObjCBridgedCastExprClass:
2426 case Stmt::CXXAddrspaceCastExprClass:
2430 case Expr::MaterializeTemporaryExprClass:
2435 case Stmt::InitListExprClass: {
2441 case Expr::CXXParenListInitExprClass:
2445 case Stmt::MemberExprClass:
2449 case Stmt::AtomicExprClass:
2453 case Stmt::ObjCIvarRefExprClass:
2457 case Stmt::ObjCForCollectionStmtClass:
2461 case Stmt::ObjCMessageExprClass:
2465 case Stmt::ObjCAtThrowStmtClass:
2466 case Stmt::CXXThrowExprClass:
2469 Engine.makePostStmtNode(S, Pred->
getState(), Pred,
true);
2472 case Stmt::ReturnStmtClass:
2476 case Stmt::OffsetOfExprClass:
2480 case Stmt::UnaryExprOrTypeTraitExprClass:
2485 case Stmt::StmtExprClass:
2489 case Stmt::UnaryOperatorClass: {
2491 if (AMgr.options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2501 case Stmt::PseudoObjectExprClass:
2505 case Expr::ObjCIndirectCopyRestoreExprClass:
2515 assert(CalleeSF && CallerSF);
2522 BeforeProcessingCall = N;
2537 if (SP->getStmt() == CE)
2542 if (!BeforeProcessingCall)
2581 NumTimesRetriedWithoutInlining++;
2591 unsigned MaxBlockVisit = AMgr.options.maxBlockVisitOnPath;
2595 if (AMgr.options.ShouldUnrollLoops) {
2597 State =
updateLoopStack(Term, AMgr.getASTContext(), Pred, MaxBlockVisit);
2600 return Engine.makeNode(BE, State, Pred);
2606 if (BlockCount == MaxBlockVisit - 1 && AMgr.options.ShouldWidenLoops) {
2607 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2608 return Engine.makeNode(BE, State, Pred);
2618 return Engine.makeNode(BE, WidenedState, Pred);
2622 if (BlockCount < MaxBlockVisit)
2623 return Engine.makeNode(BE, State, Pred);
2628 Engine.makeNode(BE.
withTag(&Tag), State, Pred,
true);
2640 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2646 if (!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, SF))
2648 NumMaxBlockCountReachedInInlined++;
2650 NumMaxBlockCountReached++;
2653 Engine.blocksExhausted.push_back(std::make_pair(BE, Sink));
2661 llvm::PrettyStackTraceFormat CrashInfo(
2662 "Processing block entrance B%d -> B%d",
2680 const auto *Ex = dyn_cast<Expr>(
Condition);
2685 bool bitsInit =
false;
2687 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2690 if (!
T->isIntegralOrEnumerationType())
2694 if (!bitsInit || newBits < bits) {
2699 Ex = CE->getSubExpr();
2705 if (!bitsInit || !
T->isIntegralOrEnumerationType() ||
2709 return state->getSVal(Ex, SF);
2715 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2716 if (!BO || !BO->isLogicalOp()) {
2719 Condition = BO->getRHS()->IgnoreParens();
2741 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2744 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2745 if (!BO || !BO->isLogicalOp())
2749 "Other kinds of branches are handled separately!");
2760 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2763 const Stmt *LastStmt = CS->getStmt();
2767 llvm_unreachable(
"could not resolve condition");
2771 std::pair<const ObjCForCollectionStmt *, const StackFrame *>;
2777 bool HasMoreIteraton) {
2778 assert(!State->contains<ObjCForHasMoreIterations>({O, SF}));
2779 return State->set<ObjCForHasMoreIterations>({O, SF}, HasMoreIteraton);
2785 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2786 return State->remove<ObjCForHasMoreIterations>({O, SF});
2792 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2793 return *State->get<ObjCForHasMoreIterations>({O, SF});
2799static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2802 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(ConditionStmt)) {
2803 bool HasMoreIteraton =
2810 if (HasMoreIteraton)
2811 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2813 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2816 const auto *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
2817 assert(ConditionExpr &&
"The condition must be an Expr from here!");
2821 if (
X.isUnknownOrUndef()) {
2823 if (
const auto *Ex = dyn_cast<Expr>(ConditionExpr)) {
2824 if (Ex->getType()->isIntegralOrEnumerationType()) {
2831 N->
getState()->getStateManager().getContext());
2841 if (
X.isUnknownOrUndef())
2842 return std::nullopt;
2846 return State->assume(
V);
2852 std::optional<unsigned> IterationsCompletedInLoop) {
2854 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2870 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2876 "Error evaluating branch");
2882 if (CheckersOutSet.
empty())
2890 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2892 if (StTrue && StFalse)
2903 (StTrue && StFalse) ||
2922 bool CompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2923 bool SkipTrueBranch = BothFeasible && CompletedTwoIterations;
2929 if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
2932 Dst.
insert(Engine.makeNode(BE, StTrue, PredN));
2934 }
else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2951 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2969 bool BeforeFirstIteration = IterationsCompletedInLoop == std::optional{0};
2970 bool SkipFalseBranch = BothFeasible && BeforeFirstIteration &&
2971 AMgr.options.ShouldAssumeAtLeastOneIteration;
2972 if (!SkipFalseBranch && DstF) {
2974 Dst.
insert(Engine.makeNode(BE, StFalse, PredN));
2983 llvm::ImmutableSet<const VarDecl *>)
2992 bool InitHasRun = State->contains<InitializedGlobalsSet>(VD);
2994 State = State->add<InitializedGlobalsSet>(VD);
2996 if (
const CFGBlock *DstBlock = InitHasRun ? DstT : DstF) {
3030 Dst.
insert(Engine.makeNode(BE, State, Pred));
3048 State = finishArgumentConstruction(
3063 while (SF != ToSF) {
3064 assert(SF &&
"ToSF must be a parent of FromSF!");
3065 for (
auto I : State->get<ObjectsUnderConstruction>())
3066 if (I.first.getStackFrame() == SF) {
3070 assert(I.first.getItem().getKind() ==
3072 I.first.getItem().getKind() ==
3074 State = State->remove<ObjectsUnderConstruction>(I.first);
3082 Pred = Engine.makeNode(Pred->
getLocation(), State, Pred);
3099 for (
const auto I : AfterRemovedDead)
3105 Engine.enqueueEndOfFunction(Dst, RS);
3119 assert(SwitchBlock->
succ_size() &&
"Switch must have at least one successor");
3125 llvm::iterator_range<CFGBlock::const_succ_reverse_iterator> CaseBlocks(
3132 Condition->IgnoreParens(), CheckersOutSet, Pred, *
this);
3142 std::optional<NonLoc> CondNL = CondV.
getAs<
NonLoc>();
3144 for (
const CFGBlock *CaseBlock : CaseBlocks) {
3153 assert(V1.getBitWidth() ==
3159 V2 = E->EvaluateKnownConstInt(ACtx);
3166 std::tie(StateMatching, State) =
3167 State->assumeInclusiveRange(*CondNL, V1, V2);
3171 StateMatching = State;
3174 if (StateMatching) {
3175 BlockEdge BE(SwitchBlock, CaseBlock, SF);
3176 Dst.
insert(Engine.makeNode(BE, StateMatching, Node));
3198 if (
Condition->IgnoreParenImpCasts()->getType()->isEnumeralType()) {
3199 if (
Switch->isAllEnumCasesCovered())
3203 BlockEdge BE(SwitchBlock, DefaultBlock, SF);
3204 Dst.
insert(Engine.makeNode(BE, State, Node));
3212std::optional<std::pair<SVal, QualType>>
3213ExprEngine::resolveAsLambdaCapturedVar(
const Expr *Ex,
const ValueDecl *VD,
3218 const auto *MD = dyn_cast<CXXMethodDecl>(SF->
getDecl());
3219 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3220 if (!AMgr.
options.ShouldInlineLambdas || !DeclRefEx ||
3221 !DeclRefEx->refersToEnclosingVariableOrCapture() || !MD ||
3222 !MD->getParent()->isLambda()) {
3223 return std::nullopt;
3227 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3233 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3234 if (MD->isImplicitObjectMemberFunction()) {
3237 return {{State->getLValue(FD, CXXThisVal), FD->getType()}};
3239 const ParmVarDecl *PVD = MD->getParamDecl(0);
3241 const ParamVarRegion *PVR =
3242 MRMgr.getParamVarRegion(CallSite, 0, SF);
3252 State->bindLoc(loc::MemRegionVal(PVR),
3253 State->getSVal(SelfArgExpr, SF->
getParent()), SF);
3254 SVal ParamSVal = State->getSVal(loc::MemRegionVal(PVR));
3255 return {{State->getLValue(FD, ParamSVal), FD->getType()}};
3257 return {{State->getLValue(FD, loc::MemRegionVal(PVR)), FD->getType()}};
3260 return std::nullopt;
3269 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3272 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3273 std::optional<std::pair<SVal, QualType>> VInfo =
3274 resolveAsLambdaCapturedVar(Ex, VD, Pred);
3277 VInfo = std::make_pair(state->getLValue(VD, SF), VD->getType());
3279 SVal V = VInfo->first;
3280 bool IsReference = VInfo->second->isReferenceType();
3286 V = state->getSVal(R);
3295 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
3297 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
3298 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V));
3301 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3302 SVal V = svalBuilder.getFunctionPointer(FD);
3313 if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3315 if (std::optional<std::pair<SVal, QualType>> VInfo =
3316 resolveAsLambdaCapturedVar(Ex, BD, Pred)) {
3317 auto [
V,
T] = VInfo.value();
3319 if (
T->isReferenceType()) {
3321 V = state->getSVal(R);
3326 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V,
3333 SVal Base = state->getLValue(DD, SF);
3334 if (DD->getType()->isReferenceType()) {
3336 Base = state->getSVal(R);
3344 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3346 V = state->getLValue(Field,
Base);
3349 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3350 SVal Idx = state->getSVal(ASE->getIdx(), SF);
3355 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3357 V = state->getLValue(BD->getType(), Idx,
Base);
3360 else if (
const auto *HV = BD->getHoldingVar()) {
3361 V = state->getLValue(HV, SF);
3363 if (HV->getType()->isReferenceType()) {
3365 V = state->getSVal(R);
3370 llvm_unreachable(
"An unknown case of structured binding encountered!");
3374 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3376 V = state->getSVal(R);
3386 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
3393 llvm_unreachable(
"Support for this Decl not implemented.");
3447 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3448 Expr *MEBase = ME->getBase();
3451 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3452 MEBase = CXXSCE->getSubExpr();
3473 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3478 Base = state->getSVal(R);
3482 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
Base));
3498 (A->
getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
3503 if (IsGLValueLike) {
3509 if (
T->isVoidType())
3513 state->getLValue(
T, state->getSVal(Idx, SF), state->getSVal(
Base, SF));
3516 }
else if (IsVectorType) {
3518 Dst.
insert(Engine.makePostStmtNode(A, state, Pred));
3520 llvm_unreachable(
"Array subscript should be an lValue when not \
3521a vector and not a forbidden lvalue type");
3542 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3543 if (MD->isImplicitObjectMemberFunction())
3544 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr);
3546 SVal MDVal = svalBuilder.getFunctionPointer(MD);
3548 Dst.
insert(Engine.makeNodeWithBinding(Pred, M, MDVal, state));
3554 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr,
3560 if (
const auto *SR =
3561 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3562 QualType T = SR->getPointeeStaticType();
3568 SVal L = state->getLValue(field, baseExprVal);
3577 const auto *PE = dyn_cast<ImplicitCastExpr>(
3579 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3580 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3584 if (field->getType()->isReferenceType()) {
3586 L = state->getSVal(R);
3591 Dst.
insert(Engine.makeNodeWithBinding(Pred, M, L, state,
3594 evalLoad(Dst, M, M, Pred, state, L);
3609 ValuesToInvalidate.push_back(SubExprVal);
3631 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3633 const MemRegion *MR = LocAndVal.first.getAsRegion();
3636 Escaped.push_back(LocAndVal.second);
3641 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3643 VR->getStackFrame()->inTopFrame())
3644 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3645 if (!RD->hasTrivialDestructor()) {
3646 Escaped.push_back(LocAndVal.second);
3655 SVal StoredVal = State->getSVal(MR);
3656 if (StoredVal != LocAndVal.second)
3659 Escaped.push_back(LocAndVal.second);
3662 if (Escaped.empty())
3671 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3682 if (!Invalidated || Invalidated->empty())
3695 for (
const auto I : ExplicitRegions) {
3697 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3701 for (
const auto &sym : *Invalidated) {
3702 if (SymbolsDirectlyInvalidated.count(sym))
3704 SymbolsIndirectlyInvalidated.insert(sym);
3707 if (!SymbolsDirectlyInvalidated.empty())
3712 if (!SymbolsIndirectlyInvalidated.empty())
3726 assert(!
isa<NonLoc>(Location) &&
"evalBind location should not be NonLoc!");
3737 StoreE, AtDeclInit, *
this, *PP);
3745 if (
auto AsLoc = Location.getAs<
Loc>()) {
3749 State = State->bindLoc(*AsLoc, Val, SF, !AtDeclInit);
3752 PostStore PS(StoreE, SF, Location.getAsRegion(),
nullptr);
3766 const Expr *LocationE,
3772 const Expr *StoreE = AssignE ? AssignE : LocationE;
3776 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3784 for (
const auto I : Tmp)
3785 evalBind(Dst, StoreE, I, location, Val,
false);
3790 const Expr *BoundEx,
3796 assert(!
isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3801 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3811 for (
const auto I : Tmp) {
3812 state = I->getState();
3818 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3821 const auto *SF = I->getStackFrame();
3823 Dst.
insert(Engine.makeNode(
Loc, state->BindExpr(BoundEx, SF,
V), I));
3855 ExplodedNodeSet Tmp;
3857 NodeEx, BoundEx, *
this);
3861std::pair<const ProgramPointTag *, const ProgramPointTag *>
3864 FalseTag(TagProviderName,
"Eagerly Assume False");
3866 return std::make_pair(&TrueTag, &FalseTag);
3890 State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3891 SVal V = State->getSVal(Ex, SF);
3893 if (SEV && SEV->isExpression()) {
3896 auto [StateTrue, StateFalse] = State->assume(*SEV);
3898 if (StateTrue && StateFalse) {
3899 StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3900 StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3906 StateTrue = StateTrue->BindExpr(Ex, SF, Val);
3907 PostStmt PostStmtTrue(Ex, SF, TrueTag);
3914 StateFalse = StateFalse->BindExpr(Ex, SF, Val);
3915 PostStmt PostStmtFalse(Ex, SF, FalseTag);
3925 const Expr *Ex)
const {
3926 return Ex && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3944 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3955 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3962 Dst.
insert(Engine.makePostStmtNode(A, state, Pred));
3985 for (
const auto &
Report : Class.getReports()) {
3986 const auto *PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
4004 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
4005 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
4027 llvm::raw_string_ostream Out(Buf);
4029 const bool IsDot =
true;
4030 const unsigned int Space = 1;
4033 Out <<
"{ \"state_id\": " << State->getID()
4036 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
4042 Indent(Out, Space + 1, IsDot) <<
"{ ";
4044 Out <<
", \"tag\": ";
4046 Out <<
'\"' << Tag->getDebugTag() <<
'\"';
4049 Out <<
", \"node_id\": " << OtherNode->
getID() <<
4050 ", \"is_sink\": " << OtherNode->
isSink() <<
4058 Indent(Out, Space, IsDot) <<
"],\\l";
4071 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4075 std::string Filename =
DumpGraph(Nodes);
4076 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4081 std::vector<const ExplodedNode *> Src;
4084 for (
const auto &
Class : BR.equivalenceClasses()) {
4086 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
4089 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
4096 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4097 return llvm::WriteGraph(&G,
"ExprEngine",
false,
4099 std::string(Filename));
4103 StringRef Filename) {
4104 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
4107 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
4112 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4113 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
4115 "Trimmed Exploded Graph",
4116 std::string(Filename));
4120 static int index = 0;
4124void ExprEngine::anchor() { }
4136 bool IsCompound =
T->isArrayType() ||
T->isRecordType() ||
4137 T->isAnyComplexType() ||
T->isVectorType();
4140 if (Args.size() > 1 || (E->
isPRValue() && IsCompound && !IsTransparent)) {
4142 for (
Expr *E : llvm::reverse(Args))
4146 }
else if (Args.size() == 0) {
4149 Val = S->getSVal(Args.front(), SF);
4151 Dst.
insert(Engine.makeNodeWithBinding(Pred, E, Val));
Defines the clang::ASTContext interface.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define STAT_COUNTER(VARNAME, DESC)
Defines the clang::Expr interface and subclasses for C++ expressions.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
static void printIndicesOfElementsToConstructJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
std::pair< const ObjCForCollectionStmt *, const StackFrame * > ObjCForLctxPair
static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, const StackFrame *SF, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
static void printStateTraitWithStackFrameJson(raw_ostream &Out, ProgramStateRef State, const StackFrame *SF, const char *NL, unsigned int Space, bool IsDot, const char *jsonPropertyName, Printer printer, Args &&...args)
A helper function to generalize program state trait printing.
static void printPendingInitLoopJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) typedef llvm REGISTER_TRAIT_WITH_PROGRAMSTATE(IndexOfElementToConstruct, IndexOfElementToConstructMap) typedef llvm typedef llvm::ImmutableMap< const StackFrame *, unsigned > PendingArrayDestructionMap
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const StackFrame *SF)
static void printObjectsUnderConstructionJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
static std::optional< std::pair< ProgramStateRef, ProgramStateRef > > assumeCondition(const Stmt *ConditionStmt, ExplodedNode *N)
Split the state on whether there are any more iterations left for this loop.
static void printPendingArrayDestructionsJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
static bool shouldJustCallCheckers(const Stmt *S, VisitKind K)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
This header contains the declarations of functions which are used to decide which loops should be com...
This header contains the declarations of functions which are used to widen loops which do not otherwi...
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
static bool isRecordType(QualType T)
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the Objective-C statement AST node classes.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ParentMap & getParentMap()
ASTContext & getASTContext() const
Stores options for the analyzer from the command line.
AnalysisPurgeMode AnalysisPurgeOpt
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
const CFGBlock * getPreviousBlock() const
const CFGBlock * getBlock() const
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Represents C++ object destructor implicitly generated for base object in destructor.
const CXXBaseSpecifier * getBaseSpecifier() const
Represents a single basic block in a source-level CFG.
succ_reverse_iterator succ_rend()
succ_reverse_iterator succ_rbegin()
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
unsigned getBlockID() const
unsigned succ_size() const
Represents C++ object destructor generated from a call to delete.
Represents a top-level expression in a basic block.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Represents C++ object destructor implicitly generated by compiler on various occasions.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Represents C++ base or member initializer from constructor's initialization list.
const CXXCtorInitializer * getInitializer() const
Represents the point where the lifetime of an automatic object ends.
const VarDecl * getVarDecl() const
Represents the point where a loop ends.
const Stmt * getLoopStmt() const
Represents C++ object destructor implicitly generated for member object in destructor.
const FieldDecl * getFieldDecl() const
Represents C++ allocator call.
const CXXNewExpr * getAllocatorExpr() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const Stmt * getTriggerStmt() const
const Stmt * getStmt() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
bool isStmtBranch() const
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a call to a C++ constructor.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
int64_t getID(const ASTContext &Context) const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a delete expression for memory deallocation and destructor calls, e.g.
SourceLocation getBeginLoc() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a point when we begin processing an inlined call.
CaseStmt - Represent a case statement.
Represents a single point (AST node) in the program that requires attention during construction of an...
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
@ TemporaryDestructorKind
const Stmt * getStmtOrNull() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc.
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a member of a struct/union/class.
This represents a GCC inline-assembly statement extension.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
ArrayRef< Expr * > inits() const
Represents the declaration of a label.
Represents a point when the lifetime of an automatic object ends.
Represents a point when we exit a loop.
This represents a Microsoft inline-assembly statement extension.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents Objective-C's collection statement.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
bool isConsumedExpr(Expr *E) const
Stmt * getParentIgnoreParens(Stmt *) const
Represents a parameter to a function.
Represents a program point just after an implicit call event.
Represents a program point after a store evaluation.
Represents a program point just before an implicit call event.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
const ProgramPointTag * getTag() const
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const StackFrame *SF, const ProgramPointTag *tag)
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
@ PreStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
const StackFrame * getStackFrame() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
std::string getAsString() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
std::string printToString(const SourceManager &SM) const
It represents a stack frame of the call stack.
unsigned getIndex() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const StackFrame *)> printMoreInfoPerStackFrame=[](const StackFrame *) {}) const
Prints out the call stack in json format.
const Expr * getCallSite() const
const Decl * getDecl() const
const StackFrame * getParent() const
It might return null.
const CFGBlock * getCallSiteBlock() const
const Stmt * getStmt() const
Stmt - This represents one statement.
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
int64_t getID(const ASTContext &Context) const
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isReferenceType() const
bool isVectorType() const
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.
This class is used for tools that requires cross translation unit capability.
AnalyzerOptions & options
llvm::ImmutableList< SVal > getEmptySValList()
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
BugReporter is a utility class for generating PathDiagnostics for analysis.
llvm::iterator_range< EQClasses_iterator > equivalenceClasses()
Represents an abstract call to a function or method along a particular path.
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const StackFrame *SF, const CallEvent *Call)
Run checkers for region changes.
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, bool AtDeclInit, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
Run checkers for debug-printing a ProgramState.
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
void runCheckersForEndFunction(ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForBlockEntrance(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const BlockEntrance &Entrance, ExprEngine &Eng) const
Run checkers after taking a control flow edge.
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
void runCheckersForLifetimeEnd(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const VarDecl *Decl, ExprEngine &Eng)
Run checkers for the end of a variable's lifetime.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
ExplodedNode * makeNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false) const
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location, State) pair, where the 'Location' is a ProgramPoint in...
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
pred_iterator pred_begin()
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it's predecessor has only one...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
ExplodedNode * getFirstSucc()
const ParentMap & getParentMap() const
unsigned succ_size() const
const StackFrame * getStackFrame() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
const StackFrame * getRootStackFrame() const
ProgramStateManager & getStateManager()
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx)
processCFGElement - Called by CoreEngine.
void processBranch(const Stmt *Condition, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF, std::optional< unsigned > IterationsCompletedInLoop)
ProcessBranch - Called by CoreEngine.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const StackFrame *SF, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void runCheckersForBlockEntrance(const BlockEntrance &Entrance, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BasicValueFactory & getBasicVals()
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
void processEndOfFunction(ExplodedNode *Pred, const ReturnStmt *RS=nullptr)
Called by CoreEngine.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void removeDeadOnEndOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBifurcation - Given the nodes in 'Src', eagerly assume concrete boolean values for '...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitObjCIndirectCopyRestoreExpr(const ObjCIndirectCopyRestoreExpr *OIE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
void processStaticInitializer(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves which element is being constructed in a non-POD type array.
std::string DumpGraph(bool trim=false, StringRef Filename="")
Dump graph to the specified filename.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const StackFrame *SF, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
void printJson(raw_ostream &Out, ProgramStateRef State, const StackFrame *SF, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
void ProcessLifetimeEnd(const Stmt *S, const VarDecl *D, ExplodedNode *Pred)
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves the size of the array in the pending ArrayInitLoopExpr.
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption)
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
AnalysisDeclContextManager & getAnalysisDeclContextManager()
static ProgramStateRef removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF)
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static std::pair< const ProgramPointTag *, const ProgramPointTag * > getEagerlyAssumeBifurcationTags()
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const StackFrame *SF)
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
StoreManager & getStoreManager()
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
BugReporter & getBugReporter()
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
ConstCFGElementRef getCFGElementRef() const
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
void VisitStmtExpr(const StmtExpr *SE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
static const ProgramPointTag * cleanupNodeTag()
A tag to track convenience transitions, which can be removed at cleanup.
void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static ProgramStateRef setWhetherHasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF, bool HasMoreIteraton)
Note whether this loop has any more iterations to model. These methods.
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const StackFrame *SF)
Retrieves which element is being destructed in a non-POD type array.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, ArrayRef< std::pair< SVal, SVal > > LocAndVals, const StackFrame *SF, PointerEscapeKind Kind, const CallEvent *Call)
Call PointerEscape callback when a value escapes as a result of bind.
void ConstructInitList(const Expr *Source, ArrayRef< Expr * > Args, bool IsTransparent, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
void processEndWorklist()
Called by CoreEngine when the analysis worklist has terminated.
CheckerManager & getCheckerManager() const
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
SymbolManager & getSymbolManager()
void processBeginOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
MemRegionManager & getRegionManager()
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
ExplodedNode * processCFGBlockEntrance(const BlockEntrance &BE, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
void processSwitch(const SwitchStmt *Switch, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProcessSwitch - Called by CoreEngine.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static bool hasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF)
bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const
ConstraintManager & getConstraintManager()
ProgramStateRef getInitialState(const StackFrame *InitSF)
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getNumVisitedCurrent() const
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
AnalysisManager & getAnalysisManager()
ExplodedGraph & getGraph()
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
SValBuilder & getSValBuilder()
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArrayInitLoopExpr - Transfer function for array init loop.
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
void VisitCastExpr(const CastExpr *CastE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCastExpr - Transfer function logic for all casts (implicit and explicit).
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
void VisitPseudoObjectExpr(const PseudoObjectExpr *PE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const StackFrame * getCurrStackFrame() const
Get the 'current' stack frame corresponding to the current work item (elementary analysis step handle...
const CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
void processIndirectGoto(ExplodedNodeSet &Dst, const Expr *Tgt, const CFGBlock *Dispatch, ExplodedNode *Pred)
processIndirectGoto - Called by CoreEngine.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace(ProgramStateRef State) const
Returns the most specific memory space for this memory region in the given ProgramStateRef.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
While alive, includes the current analysis stack in a crash trace.
Information about invalidation for a particular region/symbol.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrame *SF)
Return a memory region for the 'this' object reference.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const StackFrame *SF, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isUnknownOrUndef() const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
SubRegion - A region that subsets another larger region.
A class responsible for cleaning up unused symbols.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
SymbolicRegion - A special, "non-concrete" region.
Represents symbolic expression that isn't a location.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
@ PSK_DirectEscapeOnCall
The pointer has been passed to a function call directly.
@ PSK_EscapeOnBind
A pointer escapes due to binding its value to a location that the analyzer cannot track.
@ PSK_IndirectEscapeOnCall
The pointer has been passed to a function indirectly.
@ PSK_EscapeOther
The reason for pointer escape is unknown.
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
llvm::DenseSet< const Decl * > SetOfConstDecls
llvm::DenseSet< SymbolRef > InvalidatedSymbols
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const StackFrame *SF, unsigned BlockCount, ConstCFGElementRef Elem)
Get the states that result from widening the loop.
void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper)
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
bool LE(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
@ CXXThis
Parameter for C++ 'this' argument.
Diagnostic wrappers for TextAPI types for error reporting.
Describes how types, statements, expressions, and declarations should be printed.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out if a call should be inlined during evalCall().
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Traits for storing the call processing policy inside GDM.
DOTGraphTraits(bool isSimple=false)
static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G)
static bool nodeHasBugReport(const ExplodedNode *N)
static bool traverseHiddenNodes(const ExplodedNode *N, llvm::function_ref< void(const ExplodedNode *)> PreCallback, llvm::function_ref< void(const ExplodedNode *)> PostCallback, llvm::function_ref< bool(const ExplodedNode *)> Stop)
PreCallback: callback before break.
static bool isNodeHidden(const ExplodedNode *N, const ExplodedGraph *G)