63 #include "llvm/ADT/APSInt.h" 64 #include "llvm/ADT/DenseMap.h" 65 #include "llvm/ADT/ImmutableMap.h" 66 #include "llvm/ADT/ImmutableSet.h" 67 #include "llvm/ADT/Optional.h" 68 #include "llvm/ADT/SmallVector.h" 69 #include "llvm/ADT/Statistic.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/SaveAndRestore.h" 76 #include "llvm/Support/raw_ostream.h" 85 using namespace clang;
88 #define DEBUG_TYPE "ExprEngine" 91 "The # of times RemoveDeadBindings is called");
93 "The # of aborted paths due to reaching the maximum block count in " 94 "a top level function");
95 STATISTIC(NumMaxBlockCountReachedInInlined,
96 "The # of aborted paths due to reaching the maximum block count in " 97 "an inlined function");
99 "The # of times we re-evaluated a call without inlining");
120 class ConstructedObjectKey {
121 typedef std::pair<ConstructionContextItem, const LocationContext *>
122 ConstructedObjectKeyImpl;
124 const ConstructedObjectKeyImpl Impl;
126 const void *getAnyASTNodePtr()
const {
127 if (
const Stmt *S = getItem().getStmtOrNull())
130 return getItem().getCXXCtorInitializer();
139 const LocationContext *getLocationContext()
const {
return Impl.second; }
142 return getLocationContext()->getDecl()->getASTContext();
146 OS <<
"(LC" << getLocationContext()->getID() <<
',';
147 if (
const Stmt *S = getItem().getStmtOrNull())
148 OS <<
'S' << S->getID(getASTContext());
150 OS <<
'I' << getItem().getCXXCtorInitializer()->getID(getASTContext());
151 OS <<
',' << getItem().getKindAsString();
153 OS <<
" #" << getItem().getIndex();
155 if (
const Stmt *S = getItem().getStmtOrNull()) {
156 S->printPretty(OS, Helper, PP);
163 void Profile(llvm::FoldingSetNodeID &
ID)
const {
165 ID.AddPointer(Impl.second);
168 bool operator==(
const ConstructedObjectKey &RHS)
const {
169 return Impl == RHS.Impl;
172 bool operator<(
const ConstructedObjectKey &RHS)
const {
173 return Impl < RHS.Impl;
178 typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
187 static const char* TagProviderName =
"ExprEngine";
194 : CTU(CTU), AMgr(mgr),
195 AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
196 Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
197 StateMgr(getContext(), mgr.getStoreManagerCreator(),
198 mgr.getConstraintManagerCreator(), G.getAllocator(),
200 SymMgr(StateMgr.getSymbolManager()),
201 svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
203 VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) {
204 unsigned TrimInterval = mgr.
options.GraphTrimInterval;
205 if (TrimInterval != 0) {
227 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
231 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
237 if (!BT || !BT->isInteger())
240 const MemRegion *R = state->getRegion(PD, InitLoc);
262 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
266 const MemRegion *R = state->getRegion(SelfD, InitLoc);
271 state = state->assume(*LV,
true);
272 assert(state &&
"'self' cannot be null");
276 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
277 if (!MD->isStatic()) {
284 SVal V = state->getSVal(L);
286 state = state->assume(*LV,
true);
287 assert(state &&
"'this' cannot be null");
298 const Expr *InitWithAdjustments,
const Expr *Result,
299 const SubRegion **OutRegionWithAdjustments) {
305 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
310 if (OutRegionWithAdjustments)
311 *OutRegionWithAdjustments =
nullptr;
314 Result = InitWithAdjustments;
318 assert(!InitValWithAdjustments.
getAs<
Loc>() ||
352 CommaLHSs, Adjustments);
360 if (
const auto *MT = dyn_cast<MaterializeTemporaryExpr>(Result)) {
362 State = finishObjectConstruction(State, MT, LC);
363 State = State->BindExpr(Result, LC, *V);
383 for (
auto I = Adjustments.rbegin(), E = Adjustments.rend(); I != E; ++I) {
394 State = State->invalidateRegions(Reg, InitWithAdjustments,
396 nullptr,
nullptr,
nullptr);
409 SVal InitVal = State->getSVal(Init, LC);
413 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
417 if (InitValWithAdjustments.
isUnknown()) {
421 Result, LC, InitWithAdjustments->
getType(),
425 State->bindLoc(Reg.
castAs<
Loc>(), InitValWithAdjustments, LC,
false);
427 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
434 State = State->BindExpr(Result, LC, Reg);
436 State = State->BindExpr(Result, LC, InitValWithAdjustments);
442 if (OutRegionWithAdjustments)
443 *OutRegionWithAdjustments = cast<SubRegion>(Reg.
getAsRegion());
454 assert(!State->get<ObjectsUnderConstruction>(Key) ||
455 Key.getItem().getKind() ==
457 return State->set<ObjectsUnderConstruction>(Key, V);
473 assert(State->contains<ObjectsUnderConstruction>(Key));
474 return State->remove<ObjectsUnderConstruction>(Key);
480 ConstructedObjectKey Key({BTE,
true}, LC);
483 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
490 ConstructedObjectKey Key({BTE,
true}, LC);
491 assert(State->contains<ObjectsUnderConstruction>(Key));
492 return State->remove<ObjectsUnderConstruction>(Key);
498 ConstructedObjectKey Key({BTE,
true}, LC);
499 return State->contains<ObjectsUnderConstruction>(Key);
507 assert(LC &&
"ToLC must be a parent of FromLC!");
508 for (
auto I : State->get<ObjectsUnderConstruction>())
509 if (I.first.getLocationContext() == LC)
525 SVal cond,
bool assumption) {
547 for (
auto I : State->get<ObjectsUnderConstruction>()) {
548 ConstructedObjectKey Key = I.first;
549 SVal
Value = I.second;
550 if (Key.getLocationContext() != LC)
552 Key.print(Out,
nullptr, PP);
553 Out <<
" : " << Value << NL;
558 const char *NL,
const char *Sep,
561 if (!State->get<ObjectsUnderConstruction>().isEmpty()) {
562 Out << Sep <<
"Objects under construction:" << NL;
580 currStmtIdx = StmtIdx;
615 const ExplodedNode *Pred,
618 if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
640 const Stmt *ReferenceStmt,
642 const Stmt *DiagnosticStmt,
645 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
646 &&
"PostStmt is not generally supported by the SymbolReaper yet");
647 assert(LC &&
"Must pass the current (or expiring) LocationContext");
649 if (!DiagnosticStmt) {
650 DiagnosticStmt = ReferenceStmt;
651 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
654 NumRemoveDeadBindings++;
660 if (!ReferenceStmt) {
662 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
669 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
670 if (
SymbolRef Sym = I.second.getAsSymbol())
672 if (
const MemRegion *MR = I.second.getAsRegion())
690 DiagnosticStmt, *
this, K);
696 for (
const auto I : CheckedSet) {
704 "Checkers are not allowed to modify the Environment as a part of " 705 "checkDeadSymbols processing.");
707 "Checkers are not allowed to modify the Store as a part of " 708 "checkDeadSymbols processing.");
714 Bldr.
generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K);
724 "Error evaluating statement");
733 CleanedStates.Add(Pred);
737 for (
const auto I : CleanedStates) {
740 Visit(currStmt, I, DstI);
751 "Error evaluating end of the loop");
757 if(AMgr.
options.ShouldUnrollLoops)
774 "Error evaluating initializer");
778 const auto *
decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
781 SVal thisVal = State->getSVal(svalBuilder.
getCXXThis(decl, stackFrame));
793 State = finishObjectConstruction(State, BMI, LC);
795 PostStore PS(Init, LC,
nullptr,
nullptr);
804 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
812 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
815 SVal LValue = State->getSVal(Init, stackFrame);
818 InitVal = State->getSVal(*LValueLoc);
828 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
832 evalBind(Tmp, Init, Pred, FieldLoc, InitVal,
true, &PP);
845 for (
const auto I : Tmp) {
874 llvm_unreachable(
"Unexpected dtor kind.");
889 if (Opts.MayInlineCXXAllocator)
911 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
920 varType = cast<TypedValueRegion>(Region)->getValueType();
931 Pred, Dst, CallOpts);
942 SVal ArgVal = State->getSVal(Arg, LCtx);
946 if (State->isNull(ArgVal).isConstrainedTrue()) {
953 Bldr.generateNode(PP, Pred->
getState(), Pred);
966 DTy = AT->getElementType();
978 const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
990 CurDtor->getBody(),
true, Pred, Dst, {});
1000 const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
1004 State->getLValue(Member, State->getSVal(ThisVal).castAs<
Loc>());
1010 FieldVal = makeZeroElementRegion(State, FieldVal, T,
1014 CurDtor->getBody(),
false, Pred, Dst, CallOpts);
1038 if (isDestructorElided(State, BTE, LC)) {
1039 State = cleanupElidedDestructor(State, BTE, LC);
1055 assert(CleanDtorState.
size() <= 1);
1057 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
1068 T = AT->getElementType();
1077 false, CleanPred, Dst, CallOpts);
1119 State = addObjectUnderConstruction(State, BTE, LC,
UnknownVal());
1127 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1135 bool VisitSymbol(
SymbolRef Sym)
override {
1136 Symbols.insert(Sym);
1141 const CollectReachableSymbolsCallback &Scanner =
1142 State->scanReachableSymbols<CollectReachableSymbolsCallback>(V);
1144 State, Scanner.getSymbols(),
nullptr, K,
nullptr);
1154 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
1158 case Expr::ObjCIndirectCopyRestoreExprClass:
1159 case Stmt::CXXDependentScopeMemberExprClass:
1160 case Stmt::CXXInheritedCtorInitExprClass:
1161 case Stmt::CXXTryStmtClass:
1162 case Stmt::CXXTypeidExprClass:
1163 case Stmt::CXXUuidofExprClass:
1164 case Stmt::CXXFoldExprClass:
1165 case Stmt::MSPropertyRefExprClass:
1166 case Stmt::MSPropertySubscriptExprClass:
1167 case Stmt::CXXUnresolvedConstructExprClass:
1168 case Stmt::DependentScopeDeclRefExprClass:
1169 case Stmt::ArrayTypeTraitExprClass:
1170 case Stmt::ExpressionTraitExprClass:
1171 case Stmt::UnresolvedLookupExprClass:
1172 case Stmt::UnresolvedMemberExprClass:
1173 case Stmt::TypoExprClass:
1174 case Stmt::CXXNoexceptExprClass:
1175 case Stmt::PackExpansionExprClass:
1176 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1177 case Stmt::FunctionParmPackExprClass:
1178 case Stmt::CoroutineBodyStmtClass:
1179 case Stmt::CoawaitExprClass:
1180 case Stmt::DependentCoawaitExprClass:
1181 case Stmt::CoreturnStmtClass:
1182 case Stmt::CoyieldExprClass:
1183 case Stmt::SEHTryStmtClass:
1184 case Stmt::SEHExceptStmtClass:
1185 case Stmt::SEHLeaveStmtClass:
1186 case Stmt::SEHFinallyStmtClass:
1187 case Stmt::OMPParallelDirectiveClass:
1188 case Stmt::OMPSimdDirectiveClass:
1189 case Stmt::OMPForDirectiveClass:
1190 case Stmt::OMPForSimdDirectiveClass:
1191 case Stmt::OMPSectionsDirectiveClass:
1192 case Stmt::OMPSectionDirectiveClass:
1193 case Stmt::OMPSingleDirectiveClass:
1194 case Stmt::OMPMasterDirectiveClass:
1195 case Stmt::OMPCriticalDirectiveClass:
1196 case Stmt::OMPParallelForDirectiveClass:
1197 case Stmt::OMPParallelForSimdDirectiveClass:
1198 case Stmt::OMPParallelSectionsDirectiveClass:
1199 case Stmt::OMPTaskDirectiveClass:
1200 case Stmt::OMPTaskyieldDirectiveClass:
1201 case Stmt::OMPBarrierDirectiveClass:
1202 case Stmt::OMPTaskwaitDirectiveClass:
1203 case Stmt::OMPTaskgroupDirectiveClass:
1204 case Stmt::OMPFlushDirectiveClass:
1205 case Stmt::OMPOrderedDirectiveClass:
1206 case Stmt::OMPAtomicDirectiveClass:
1207 case Stmt::OMPTargetDirectiveClass:
1208 case Stmt::OMPTargetDataDirectiveClass:
1209 case Stmt::OMPTargetEnterDataDirectiveClass:
1210 case Stmt::OMPTargetExitDataDirectiveClass:
1211 case Stmt::OMPTargetParallelDirectiveClass:
1212 case Stmt::OMPTargetParallelForDirectiveClass:
1213 case Stmt::OMPTargetUpdateDirectiveClass:
1214 case Stmt::OMPTeamsDirectiveClass:
1215 case Stmt::OMPCancellationPointDirectiveClass:
1216 case Stmt::OMPCancelDirectiveClass:
1217 case Stmt::OMPTaskLoopDirectiveClass:
1218 case Stmt::OMPTaskLoopSimdDirectiveClass:
1219 case Stmt::OMPDistributeDirectiveClass:
1220 case Stmt::OMPDistributeParallelForDirectiveClass:
1221 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1222 case Stmt::OMPDistributeSimdDirectiveClass:
1223 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1224 case Stmt::OMPTargetSimdDirectiveClass:
1225 case Stmt::OMPTeamsDistributeDirectiveClass:
1226 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1227 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1228 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1229 case Stmt::OMPTargetTeamsDirectiveClass:
1230 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1231 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1232 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1233 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1234 case Stmt::CapturedStmtClass: {
1236 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1240 case Stmt::ParenExprClass:
1241 llvm_unreachable(
"ParenExprs already handled.");
1242 case Stmt::GenericSelectionExprClass:
1243 llvm_unreachable(
"GenericSelectionExprs already handled.");
1246 case Stmt::BreakStmtClass:
1247 case Stmt::CaseStmtClass:
1248 case Stmt::CompoundStmtClass:
1249 case Stmt::ContinueStmtClass:
1250 case Stmt::CXXForRangeStmtClass:
1251 case Stmt::DefaultStmtClass:
1252 case Stmt::DoStmtClass:
1253 case Stmt::ForStmtClass:
1254 case Stmt::GotoStmtClass:
1255 case Stmt::IfStmtClass:
1256 case Stmt::IndirectGotoStmtClass:
1257 case Stmt::LabelStmtClass:
1259 case Stmt::NullStmtClass:
1260 case Stmt::SwitchStmtClass:
1261 case Stmt::WhileStmtClass:
1262 case Expr::MSDependentExistsStmtClass:
1263 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1265 case Stmt::ObjCSubscriptRefExprClass:
1266 case Stmt::ObjCPropertyRefExprClass:
1267 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1269 case Stmt::GNUNullExprClass: {
1273 svalBuilder.makeIntValWithPtrWidth(0,
false));
1278 case Stmt::ObjCAtSynchronizedStmtClass:
1284 case Expr::ConstantExprClass:
1285 case Stmt::ExprWithCleanupsClass:
1289 case Stmt::CXXBindTemporaryExprClass: {
1301 case Stmt::DesignatedInitExprClass:
1302 case Stmt::DesignatedInitUpdateExprClass:
1303 case Stmt::ArrayInitLoopExprClass:
1304 case Stmt::ArrayInitIndexExprClass:
1305 case Stmt::ExtVectorElementExprClass:
1306 case Stmt::ImaginaryLiteralClass:
1307 case Stmt::ObjCAtCatchStmtClass:
1308 case Stmt::ObjCAtFinallyStmtClass:
1309 case Stmt::ObjCAtTryStmtClass:
1310 case Stmt::ObjCAutoreleasePoolStmtClass:
1311 case Stmt::ObjCEncodeExprClass:
1312 case Stmt::ObjCIsaExprClass:
1313 case Stmt::ObjCProtocolExprClass:
1314 case Stmt::ObjCSelectorExprClass:
1315 case Stmt::ParenListExprClass:
1316 case Stmt::ShuffleVectorExprClass:
1317 case Stmt::ConvertVectorExprClass:
1318 case Stmt::VAArgExprClass:
1319 case Stmt::CUDAKernelCallExprClass:
1320 case Stmt::OpaqueValueExprClass:
1321 case Stmt::AsTypeExprClass:
1326 case Stmt::PredefinedExprClass:
1327 case Stmt::AddrLabelExprClass:
1328 case Stmt::AttributedStmtClass:
1329 case Stmt::IntegerLiteralClass:
1330 case Stmt::FixedPointLiteralClass:
1331 case Stmt::CharacterLiteralClass:
1332 case Stmt::ImplicitValueInitExprClass:
1333 case Stmt::CXXScalarValueInitExprClass:
1334 case Stmt::CXXBoolLiteralExprClass:
1335 case Stmt::ObjCBoolLiteralExprClass:
1336 case Stmt::ObjCAvailabilityCheckExprClass:
1337 case Stmt::FloatingLiteralClass:
1338 case Stmt::NoInitExprClass:
1339 case Stmt::SizeOfPackExprClass:
1340 case Stmt::StringLiteralClass:
1341 case Stmt::ObjCStringLiteralClass:
1342 case Stmt::CXXPseudoDestructorExprClass:
1343 case Stmt::SubstNonTypeTemplateParmExprClass:
1344 case Stmt::CXXNullPtrLiteralExprClass:
1345 case Stmt::OMPArraySectionExprClass:
1346 case Stmt::TypeTraitExprClass: {
1355 case Stmt::CXXDefaultArgExprClass:
1356 case Stmt::CXXDefaultInitExprClass: {
1365 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
1366 ArgE = DefE->getExpr();
1367 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
1368 ArgE = DefE->getExpr();
1370 llvm_unreachable(
"unknown constant wrapper kind");
1372 bool IsTemporary =
false;
1373 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1374 ArgE = MTE->GetTemporaryExpr();
1383 for (
const auto I : PreVisit) {
1385 State = State->BindExpr(S, LCtx, *ConstantVal);
1387 State = createTemporaryRegionIfNeeded(State, LCtx,
1399 case Stmt::CXXStdInitializerListExprClass:
1400 case Expr::ObjCArrayLiteralClass:
1401 case Expr::ObjCDictionaryLiteralClass:
1402 case Expr::ObjCBoxedExprClass: {
1411 const auto *Ex = cast<Expr>(S);
1412 QualType resultType = Ex->getType();
1414 for (
const auto N : preVisit) {
1416 SVal result = svalBuilder.conjureSymbolVal(
nullptr, Ex, LCtx,
1418 currBldrCtx->blockCount());
1423 if (!(isa<ObjCBoxedExpr>(Ex) &&
1424 !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
1426 for (
auto Child : Ex->children()) {
1428 SVal Val = State->getSVal(Child, LCtx);
1440 case Stmt::ArraySubscriptExprClass:
1446 case Stmt::GCCAsmStmtClass:
1452 case Stmt::MSAsmStmtClass:
1458 case Stmt::BlockExprClass:
1464 case Stmt::LambdaExprClass:
1465 if (AMgr.options.ShouldInlineLambdas) {
1471 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1475 case Stmt::BinaryOperatorClass: {
1476 const auto *B = cast<BinaryOperator>(S);
1477 if (B->isLogicalOp()) {
1483 else if (B->getOpcode() == BO_Comma) {
1487 state->getSVal(B->getRHS(),
1494 if (AMgr.options.ShouldEagerlyAssume &&
1495 (B->isRelationalOp() || B->isEqualityOp())) {
1507 case Stmt::CXXOperatorCallExprClass: {
1508 const auto *OCE = cast<CXXOperatorCallExpr>(S);
1512 const Decl *Callee = OCE->getCalleeDecl();
1513 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1514 if (MD->isInstance()) {
1518 createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
1519 if (NewState != State) {
1532 case Stmt::CallExprClass:
1533 case Stmt::CXXMemberCallExprClass:
1534 case Stmt::UserDefinedLiteralClass:
1540 case Stmt::CXXCatchStmtClass:
1546 case Stmt::CXXTemporaryObjectExprClass:
1547 case Stmt::CXXConstructExprClass:
1553 case Stmt::CXXNewExprClass: {
1560 for (
const auto i : PreVisit)
1568 case Stmt::CXXDeleteExprClass: {
1571 const auto *CDE = cast<CXXDeleteExpr>(S);
1574 for (
const auto i : PreVisit)
1583 case Stmt::ChooseExprClass: {
1585 const auto *C = cast<ChooseExpr>(S);
1591 case Stmt::CompoundAssignOperatorClass:
1597 case Stmt::CompoundLiteralExprClass:
1603 case Stmt::BinaryConditionalOperatorClass:
1604 case Stmt::ConditionalOperatorClass: {
1606 const auto *C = cast<AbstractConditionalOperator>(S);
1612 case Stmt::CXXThisExprClass:
1618 case Stmt::DeclRefExprClass: {
1620 const auto *DE = cast<DeclRefExpr>(S);
1626 case Stmt::DeclStmtClass:
1632 case Stmt::ImplicitCastExprClass:
1633 case Stmt::CStyleCastExprClass:
1634 case Stmt::CXXStaticCastExprClass:
1635 case Stmt::CXXDynamicCastExprClass:
1636 case Stmt::CXXReinterpretCastExprClass:
1637 case Stmt::CXXConstCastExprClass:
1638 case Stmt::CXXFunctionalCastExprClass:
1639 case Stmt::ObjCBridgedCastExprClass: {
1641 const auto *C = cast<CastExpr>(S);
1643 VisitCast(C, C->getSubExpr(), Pred, dstExpr);
1651 case Expr::MaterializeTemporaryExprClass: {
1653 const auto *MTE = cast<MaterializeTemporaryExpr>(S);
1657 for (
const auto i : dstPrevisit)
1664 case Stmt::InitListExprClass:
1670 case Stmt::MemberExprClass:
1676 case Stmt::AtomicExprClass:
1682 case Stmt::ObjCIvarRefExprClass:
1688 case Stmt::ObjCForCollectionStmtClass:
1694 case Stmt::ObjCMessageExprClass:
1700 case Stmt::ObjCAtThrowStmtClass:
1701 case Stmt::CXXThrowExprClass:
1707 case Stmt::ReturnStmtClass:
1713 case Stmt::OffsetOfExprClass: {
1719 for (
const auto Node : PreVisit)
1727 case Stmt::UnaryExprOrTypeTraitExprClass:
1734 case Stmt::StmtExprClass: {
1735 const auto *SE = cast<StmtExpr>(S);
1737 if (SE->getSubStmt()->body_empty()) {
1740 &&
"Empty statement expression must have void type.");
1744 if (
const auto *LastExpr =
1745 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
1749 state->getSVal(LastExpr,
1755 case Stmt::UnaryOperatorClass: {
1757 const auto *U = cast<UnaryOperator>(S);
1758 if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
1769 case Stmt::PseudoObjectExprClass: {
1772 const auto *PE = cast<PseudoObjectExpr>(S);
1773 if (
const Expr *Result = PE->getResultExpr()) {
1789 bool ExprEngine::replayWithoutInlining(
ExplodedNode *N,
1793 assert(CalleeSF && CallerSF);
1800 BeforeProcessingCall = N;
1815 if (SP->getStmt() == CE)
1820 if (!BeforeProcessingCall)
1837 ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState,
false, &IsNew);
1848 NumTimesRetriedWithoutInlining++;
1859 if(AMgr.options.ShouldUnrollLoops) {
1860 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
1864 Pred, maxBlockVisitOnPath);
1865 if (NewState != Pred->
getState()) {
1880 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
1881 AMgr.options.ShouldWidenLoops) {
1884 (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1895 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
1905 (*G.roots_begin())->getLocation().getLocationContext();
1907 Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->
getDecl());
1913 if ((!AMgr.options.NoRetryExhausted &&
1914 replayWithoutInlining(Pred, CalleeLC)))
1916 NumMaxBlockCountReachedInInlined++;
1918 NumMaxBlockCountReached++;
1921 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1935 const Stmt *Condition,
1939 const auto *Ex = dyn_cast<
Expr>(Condition);
1941 return UnknownVal();
1944 bool bitsInit =
false;
1946 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
1950 return UnknownVal();
1953 if (!bitsInit || newBits < bits) {
1958 Ex = CE->getSubExpr();
1966 return UnknownVal();
1968 return state->getSVal(Ex, LCtx);
1975 if (!BO || !BO->isLogicalOp()) {
1978 Condition = BO->getRHS()->IgnoreParens();
2000 if (
const auto *Ex = dyn_cast<Expr>(Condition))
2001 Condition = Ex->IgnoreParens();
2004 if (!BO || !BO->isLogicalOp())
2008 "Temporary destructor branches handled by processBindTemporary.");
2019 for (; I != E; ++I) {
2024 const Stmt *LastStmt = CS->getStmt();
2028 llvm_unreachable(
"could not resolve condition");
2037 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
2038 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2041 currBldrCtx = &BldCtx;
2051 if (
const auto *Ex = dyn_cast<Expr>(Condition))
2052 Condition = Ex->IgnoreParens();
2057 "Error evaluating branch");
2063 if (CheckersOutSet.empty())
2067 for (
const auto PredI : CheckersOutSet) {
2068 if (PredI->isSink())
2072 SVal X = PrevState->getSVal(Condition, PredI->getLocationContext());
2076 if (
const auto *Ex = dyn_cast<Expr>(Condition)) {
2077 if (Ex->getType()->isIntegralOrEnumerationType()) {
2083 PredI->getLocationContext(),
2103 std::tie(StTrue, StFalse) = PrevState->assume(V);
2121 currBldrCtx =
nullptr;
2127 llvm::ImmutableSet<const VarDecl *>)
2130 NodeBuilderContext &BuilderCtx,
2132 ExplodedNodeSet &Dst,
2135 PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
2136 currBldrCtx = &BuilderCtx;
2140 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
2141 BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF);
2144 state = state->add<InitializedGlobalsSet>(VD);
2147 builder.generateNode(state, initHasRun, Pred);
2148 builder.markInfeasible(!initHasRun);
2150 currBldrCtx =
nullptr;
2171 for (iterator I = builder.
begin(), E = builder.
end(); I != E; ++I) {
2172 if (I.getLabel() == L) {
2178 llvm_unreachable(
"No block with label.");
2192 for (iterator I = builder.
begin(), E = builder.
end(); I != E; ++I)
2212 State = finishArgumentConstruction(
2227 while (LC != ToLC) {
2228 assert(LC &&
"ToLC must be a parent of FromLC!");
2229 for (
auto I : State->get<ObjectsUnderConstruction>())
2230 if (I.first.getLocationContext() == LC) {
2234 assert(I.first.getItem().getKind() ==
2236 I.first.getItem().getKind() ==
2238 State = State->remove<ObjectsUnderConstruction>(I.first);
2256 assert(areAllObjectsFullyConstructed(Pred->
getState(),
2261 StateMgr.EndPath(Pred->
getState());
2270 for (
const auto I : AfterRemovedDead)
2276 Engine.enqueueEndOfFunction(Dst, RS);
2288 if (CondV_untested.
isUndef()) {
2299 iterator I = builder.
begin(), EI = builder.
end();
2300 bool defaultIsFeasible = I == EI;
2302 for ( ; I != EI; ++I) {
2307 const CaseStmt *Case = I.getCase();
2322 std::tie(StateCase, DefaultSt) =
2323 DefaultSt->assumeInclusiveRange(*NL, V1, V2);
2325 StateCase = DefaultSt;
2333 defaultIsFeasible =
true;
2335 defaultIsFeasible =
false;
2340 if (!defaultIsFeasible)
2372 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2375 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
2377 const Decl *D = LocCtxt->getDecl();
2378 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
2379 const auto *DeclRefEx = dyn_cast<
DeclRefExpr>(Ex);
2382 if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
2383 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
2384 MD->getParent()->isLambda()) {
2387 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
2393 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
2395 svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame());
2396 SVal CXXThisVal = state->getSVal(CXXThis);
2397 VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
2402 VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
2404 SVal V = VInfo->first;
2405 bool IsReference = VInfo->second->isReferenceType();
2410 if (
const MemRegion *R = V.getAsRegion())
2411 V = state->getSVal(R);
2416 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2420 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
2422 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
2423 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
2426 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2427 SVal V = svalBuilder.getFunctionPointer(FD);
2428 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2432 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
2438 SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx,
getContext().VoidPtrTy,
2439 currBldrCtx->blockCount());
2441 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2445 if (isa<BindingDecl>(D)) {
2451 llvm_unreachable(
"Support for this Decl not implemented.");
2475 for (
auto *
Node : CheckerPreStmt) {
2479 if (IsGLValueLike) {
2488 SVal V = state->getLValue(T,
2489 state->getSVal(Idx, LCtx),
2490 state->getSVal(Base, LCtx));
2493 }
else if (IsVectorType) {
2497 llvm_unreachable(
"Array subscript should be an lValue when not \ 2498 a vector and not a forbidden lvalue type");
2517 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2518 for (
const auto I : CheckedSet)
2524 for (
const auto I : CheckedSet) {
2530 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Member)) {
2531 if (MD->isInstance())
2532 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2534 SVal MDVal = svalBuilder.getFunctionPointer(MD);
2535 state = state->BindExpr(M, LCtx, MDVal);
2543 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr,
2549 const auto *field = cast<FieldDecl>(Member);
2550 SVal L = state->getLValue(field, baseExprVal);
2561 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
2562 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
2566 if (field->getType()->isReferenceType()) {
2567 if (
const MemRegion *R = L.getAsRegion())
2568 L = state->getSVal(R);
2573 Bldr.
generateNode(M, I, state->BindExpr(M, LCtx, L),
nullptr,
2597 for (
const auto I : AfterPreSet) {
2602 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
2604 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
2605 ValuesToInvalidate.push_back(SubExprVal);
2608 State = State->invalidateRegions(ValuesToInvalidate, AE,
2609 currBldrCtx->blockCount(),
2615 State = State->BindExpr(AE, LCtx, ResultVal);
2633 bool escapes =
true;
2637 escapes = !regionLoc->getRegion()->hasStackStorage();
2645 SVal StoredVal = State->getSVal(regionLoc->getRegion());
2646 if (StoredVal != Val)
2647 escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
2669 if (!Invalidated || Invalidated->empty())
2682 for (
const auto I : ExplicitRegions) {
2684 SymbolsDirectlyInvalidated.insert(R->getSymbol());
2688 for (
const auto &sym : *Invalidated) {
2689 if (SymbolsDirectlyInvalidated.count(sym))
2691 SymbolsIndirectlyInvalidated.insert(sym);
2694 if (!SymbolsDirectlyInvalidated.empty())
2699 if (!SymbolsIndirectlyInvalidated.empty())
2720 StoreE, *
this, *PP);
2735 for (
const auto PredI : CheckedSet) {
2743 state = state->bindLoc(location.
castAs<
Loc>(),
2744 Val, LC, !atDeclInit);
2749 LocReg = LocRegVal->getRegion();
2766 const Expr *LocationE,
2772 const Expr *StoreE = AssignE ? AssignE : LocationE;
2776 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
2784 for (
const auto I : Tmp)
2785 evalBind(Dst, StoreE, I, location, Val,
false);
2790 const Expr *BoundEx,
2796 assert(!location.
getAs<
NonLoc>() &&
"location cannot be a NonLoc.");
2801 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
2810 for (
const auto I : Tmp) {
2811 state = I->getState();
2818 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
2821 Bldr.
generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx, V), tag,
2828 const Stmt *BoundEx,
2857 NodeEx, BoundEx, *
this);
2861 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2864 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2865 "Eagerly Assume True"),
2866 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2867 "Eagerly Assume False");
2868 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2869 &eagerlyAssumeBinOpBifurcationFalse);
2877 for (
const auto Pred : Src) {
2889 if (SEV && SEV->isExpression()) {
2890 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2894 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2898 SVal Val = svalBuilder.makeIntVal(1U, Ex->
getType());
2905 SVal Val = svalBuilder.makeIntVal(0U, Ex->
getType());
2955 N->getState()->getStateManager().getOwningEngine()).
getBugReporter();
2957 const auto EQClasses =
2958 llvm::make_range(BR.EQClasses_begin(), BR.EQClasses_end());
2960 for (
const auto &EQ : EQClasses) {
2961 for (
const BugReport &Report : EQ) {
2962 if (Report.getErrorNode() == N)
2973 static bool traverseHiddenNodes(
2974 const ExplodedNode *N,
2975 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
2976 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
2977 llvm::function_ref<
bool(
const ExplodedNode *)> Stop) {
2978 const ExplodedNode *FirstHiddenNode = N;
2979 while (FirstHiddenNode->pred_size() == 1 &&
2980 isNodeHidden(*FirstHiddenNode->pred_begin())) {
2981 FirstHiddenNode = *FirstHiddenNode->pred_begin();
2983 const ExplodedNode *OtherNode = FirstHiddenNode;
2985 PreCallback(OtherNode);
2986 if (Stop(OtherNode))
2991 PostCallback(OtherNode);
2993 OtherNode = *OtherNode->succ_begin();
2998 static std::string getNodeAttributes(
const ExplodedNode *N,
3001 auto Noop = [](
const ExplodedNode*){};
3003 Out.push_back(
"style=filled");
3004 Out.push_back(
"fillcolor=red");
3007 if (traverseHiddenNodes(N, Noop, Noop,
3008 [](
const ExplodedNode *
C) {
return C->isSink(); }))
3009 Out.push_back(
"color=blue");
3010 return llvm::join(Out,
",");
3013 static bool isNodeHidden(
const ExplodedNode *N) {
3014 return N->isTrivial();
3017 static std::string getNodeLabel(
const ExplodedNode *N, ExplodedGraph *G){
3019 llvm::raw_string_ostream Out(sbuf);
3024 traverseHiddenNodes(
3026 [&](
const ExplodedNode *OtherNode) {
3027 OtherNode->getLocation().print(
"\\l", Out);
3029 Out <<
"\\lTag:" << Tag->getTagDescription();
3031 Out <<
"\\lNode is sink\\l";
3033 Out <<
"\\lBug report attached\\l";
3035 [&](
const ExplodedNode *) { Out <<
"\\l--------\\l"; },
3036 [&](
const ExplodedNode *) {
return false; });
3040 Out <<
"StateID: ST" << State->getID() <<
", NodeID: N" << N->getID(G)
3041 <<
" <" << (
const void *)N <<
">\\|";
3044 std::all_of(N->pred_begin(), N->pred_end(), [&](
const ExplodedNode *
P) {
3045 return P->getState() ==
State;
3047 if (!SameAsAllPredecessors)
3048 State->printDOT(Out, N->getLocationContext());
3059 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
3061 llvm::errs() <<
"Warning: viewing graph requires assertions" <<
"\n";
3068 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
3070 llvm::errs() <<
"Warning: viewing graph requires assertions" <<
"\n";
3076 std::vector<const ExplodedNode *> Src;
3080 EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
3081 const auto *N =
const_cast<ExplodedNode *
>(EI->begin()->getErrorNode());
3082 if (N) Src.push_back(N);
3086 return llvm::WriteGraph(&G,
"ExprEngine",
false,
3087 "Exploded Graph", Filename);
3090 llvm::errs() <<
"Warning: dumping graph requires assertions" <<
"\n";
3095 StringRef Filename) {
3097 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
3099 if (!TrimmedG.get()) {
3100 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
3102 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
3104 "Trimmed Exploded Graph",
3108 llvm::errs() <<
"Warning: dumping graph requires assertions" <<
"\n";
3113 static int index = 0;
void processEndWorklist() override
Called by CoreEngine when the analysis worklist has terminated.
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
Defines the clang::ASTContext interface.
Represents C++ allocator call.
This represents a GCC inline-assembly statement extension.
TypedValueRegion - An abstract class representing regions having a typed value.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
Expr * getInit() const
Get the initializer.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
enum clang::SubobjectAdjustment::@45 Kind
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
bool isMemberPointerType() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
void markInfeasible(bool branch)
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...
const Stmt * getStmt() const
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
bool operator==(CanQual< T > x, CanQual< U > y)
static bool nodeHasBugReport(const ExplodedNode *N)
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C...
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
Stmt - This represents one statement.
Information about invalidation for a particular region/symbol.
This builder class is useful for generating nodes that resulted from visiting a statement.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2)
C Language Family Type Representation.
Defines the SourceManager interface.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
Decl - This represents one declaration (or definition), e.g.
Represents a point when we begin processing an inlined call.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
FunctionDecl * getOperatorNew() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
const CastExpr * BasePath
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T)
void processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
ProcessBranch - Called by CoreEngine.
The pointer has been passed to a function indirectly.
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, NodeBuilderContext &BldCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
Represents C++ object destructor generated from a call to delete.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Hints for figuring out of a call should be inlined during evalCall().
Represents a program point just before an implicit call event.
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
const ProgramStateRef & getState() const
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred) override
Called by CoreEngine when processing the entrance of a CFGBlock.
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2)
Represents a point when we exit a loop.
ProgramStateRef getInitialState(const LocationContext *InitLoc) override
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
bool isIndirectMemberInitializer() const
bool isConsumedExpr(Expr *E) const
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void takeNodes(const ExplodedNodeSet &S)
Represents a variable declaration or definition.
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion *> ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits) override
Call PointerEscape callback when a value escapes as a result of region invalidation.
ASTContext & getASTContext() const
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) static const char *TagProviderName
const T * getAs() const
Member-template getAs<specific type>'.
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
static Optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)
By looking at a certain item that may be potentially part of an object's ConstructionContext, retrieve such object's location.
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
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.
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
const ElementRegion * GetElementZeroRegion(const SubRegion *R, QualType T)
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const Stmt * getTriggerStmt() const
Describes how types, statements, expressions, and declarations should be printed. ...
Defines the Objective-C statement AST node classes.
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state...
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BoundNodesTreeBuilder Nodes
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC)
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
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.
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
One of these records is kept for each identifier that is lexed.
A pointer escapes due to binding its value to a location that the analyzer cannot track...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a member of a struct/union/class.
Represents a program point after a store evaluation.
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
bool isReferenceType() const
void dumpStack(raw_ostream &OS, StringRef Indent={}, const char *NL="\, const char *Sep="", std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
const StackFrameContext * getStackFrame() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) override
Call PointerEscape callback when a value escapes as a result of bind.
static bool isLocType(QualType T)
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc...
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
SourceLocation getBeginLoc() const LLVM_READONLY
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called")
const LocationContext * getLocationContext() const
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const clang::PrintingPolicy & getPrintingPolicy() const
static bool isRecordType(QualType T)
const LocationContext * getParent() const
A builtin binary operation expression such as "x + y" or "x <= y".
If a crash happens while one of these objects are live, the message is printed out along with the spe...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
const VarDecl * getVarDecl() const
CaseStmt - Represent a case statement.
const CXXBaseSpecifier * getBaseSpecifier() const
bool isAnyMemberInitializer() const
An adjustment to be made to the temporary created when emitting a reference binding, which accesses a particular subobject of that temporary.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Represents binding an expression to a temporary.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
FieldDecl * getAnyMember() const
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
static bool nodeHasBugReport(const ExplodedNode *N)
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void processStaticInitializer(const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
const CFGBlock * getCallSiteBlock() const
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit=false, const ProgramPoint *PP=nullptr)
evalBind - Handle the semantics of binding a value to a specific location.
CheckerManager & getCheckerManager() const
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
CXXCtorInitializer * getInitializer() const
void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep)
Run checkers for debug-printing a ProgramState.
void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const FieldDecl * getFieldDecl() const
const Stmt * getCallSite() const
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Represents a single basic block in a source-level CFG.
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
SymbolicRegion - A special, "non-concrete" region.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
void processSwitch(SwitchNodeBuilder &builder) override
ProcessSwitch - Called by CoreEngine.
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep, const LocationContext *LCtx=nullptr) override
printState - Called by ProgramStateManager to print checker-specific data.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L) override
Called by CoreEngine.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
Defines the clang::LangOptions interface.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const Expr * getCondition() const
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Gets an outside caller given a callee context.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
Represents a C++ destructor within a class.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
This is the simplest builder which generates nodes in the ExplodedGraph.
void Add(ExplodedNode *N)
The pointer has been passed to a function call directly.
QualType getConditionType() const
const LocationContext * getLocationContext() const
bool isTemporaryDtorsBranch() const
DOTGraphTraits(bool isSimple=false)
bool inTopFrame() const override
Return true if the current LocationContext has no caller context.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void FlushReports()
Generate and flush diagnostics for all bug reports.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
The reason for pointer escape is unknown.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Traits for storing the call processing policy inside GDM.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
This represents a Microsoft inline-assembly statement extension.
const SwitchStmt * getSwitch() const
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.
Represents C++ object destructor implicitly generated for base object in destructor.
QualType getDestroyedType() const
Retrieve the type being destroyed.
const Expr * getSubExpr() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
reverse_iterator rbegin()
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
const MemRegion * getRegion() const
Get the underlining region.
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
While alive, includes the current analysis stack in a crash trace.
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS=nullptr) override
Called by CoreEngine.
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
CFGTerminator getTerminator()
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx, NodeBuilderContext *Ctx) override
processCFGElement - Called by CoreEngine.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
const LocationContext * getLocationContext() const
const Stmt * getStmt() const
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, const Stmt *LoopStmt)
Get the states that result from widening the loop.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
DOTGraphTraits(bool isSimple=false)
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
AnalysisManager & getAnalysisManager() override
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic expressions of ...
const MemRegion * getAsRegion() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
SourceLocation getBeginLoc() const
CallEventManager & getCallEventManager()
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
Represents the declaration of a label.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
void processIndirectGoto(IndirectGotoNodeBuilder &builder) override
processIndirectGoto - Called by CoreEngine.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
AnalyzerOptions & options
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
BugReporter & getBugReporter()
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
A class responsible for cleaning up unused symbols.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
bool isVectorType() const
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
void insert(const ExplodedNodeSet &S)
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Defines various enumerations that describe declaration and type specifiers.
StringRef getName() const
Return the actual identifier string.
ast_type_traits::DynTypedNode Node
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
Dataflow Directional Tag Classes.
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
SValBuilder & getSValBuilder()
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
void addNodes(const ExplodedNodeSet &S)
StoreManager & getStoreManager()
Represents a program point just after an implicit call event.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) override
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store...
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, const EvalCallOptions &Options)
const NodeBuilderContext & getContext()
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
This node builder keeps track of the generated sink nodes.
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
StmtClass getStmtClass() const
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
const Decl * getSingleDecl() const
Represents symbolic expression that isn't a location.
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Represents an abstract call to a function or method along a particular path.
ProgramStateRef getState() const
const Stmt * getLoopStmt() const
ProgramStateManager & getStateManager() override
This class is used for tools that requires cross translation unit capability.
const Decl * getDecl() const
const CXXDeleteExpr * getDeleteExpr() const
Represents a single point (AST node) in the program that requires attention during construction of an...
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
const CXXTempObjectRegion * getCXXStaticTempObjectRegion(const Expr *Ex)
Create a CXXTempObjectRegion for temporaries which are lifetime-extended by static references...
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
SwitchStmt - This represents a 'switch' stmt.
SourceLocation getBeginLoc() const
unsigned getIntWidth(QualType T) const
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
static void printObjectsUnderConstructionForContext(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LC)
SubRegion - A region that subsets another larger region.
Represents a C++ base or member initializer.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getIndex() const
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
IndirectFieldDecl * getIndirectMember() const
const LocationContext * getLocationContext() const
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const StackFrameContext * getStackFrame() const
llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator
Iterator over the set of BugReports tracked by the BugReporter.
Represents a base class of a C++ class.
Stores options for the analyzer from the command line.
void getCaptureFields(llvm::DenseMap< const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
const CXXNewExpr * getAllocatorExpr() const
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
bool SameAsAllPredecessors
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
Represents C++ object destructor implicitly generated by compiler on various occasions.
ProgramStateRef getState() const
pred_iterator pred_begin()
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
Represents a top-level expression in a basic block.
This class is used for builtin types like 'int'.
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption) override
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
Represents C++ object destructor implicitly generated for member object in destructor.
const MemRegion * getBaseRegion() const
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
static Decl::Kind getKind(const Decl *D)
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
std::string DumpGraph(bool trim=false, StringRef Filename="")
Dump graph to the specified filename.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
A reference to a declared variable, function, enum, etc.
Represents C++ base or member initializer from constructor's initialization list. ...
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
const StackFrameContext * getStackFrame() const
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
ParentMap & getParentMap()
ProgramStateRef escapeValue(ProgramStateRef State, SVal V, PointerEscapeKind K) const
A simple wrapper when you only need to notify checkers of pointer-escape of a single value...
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
This represents a decl that may have a name.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
ConstraintManager & getConstraintManager()
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
AnalysisDeclContext * getAnalysisDeclContext() const
bool isFeasible(bool branch)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, const LocationContext *LCtx, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
const Expr * getTarget() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
bool isUnknownOrUndef() const
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
QualType getType() const
Retrieves the type of the base class.
Represents the point where a loop ends.