File indexing completed on 2026-05-10 08:37:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
0016 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
0017
0018 #include "clang/AST/Expr.h"
0019 #include "clang/AST/Type.h"
0020 #include "clang/Analysis/CFG.h"
0021 #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
0022 #include "clang/Analysis/ProgramPoint.h"
0023 #include "clang/Basic/LLVM.h"
0024 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
0025 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
0026 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
0027 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
0028 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
0029 #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
0030 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
0031 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
0032 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0033 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
0034 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
0035 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0036 #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
0037 #include "llvm/ADT/ArrayRef.h"
0038 #include <cassert>
0039 #include <optional>
0040 #include <utility>
0041
0042 namespace clang {
0043
0044 class AnalysisDeclContextManager;
0045 class AnalyzerOptions;
0046 class ASTContext;
0047 class CFGBlock;
0048 class CFGElement;
0049 class ConstructionContext;
0050 class CXXBindTemporaryExpr;
0051 class CXXCatchStmt;
0052 class CXXConstructExpr;
0053 class CXXDeleteExpr;
0054 class CXXNewExpr;
0055 class CXXThisExpr;
0056 class Decl;
0057 class DeclStmt;
0058 class GCCAsmStmt;
0059 class LambdaExpr;
0060 class LocationContext;
0061 class MaterializeTemporaryExpr;
0062 class MSAsmStmt;
0063 class NamedDecl;
0064 class ObjCAtSynchronizedStmt;
0065 class ObjCForCollectionStmt;
0066 class ObjCIvarRefExpr;
0067 class ObjCMessageExpr;
0068 class ReturnStmt;
0069 class Stmt;
0070
0071 namespace cross_tu {
0072
0073 class CrossTranslationUnitContext;
0074
0075 }
0076
0077 namespace ento {
0078
0079 class AnalysisManager;
0080 class BasicValueFactory;
0081 class CallEvent;
0082 class CheckerManager;
0083 class ConstraintManager;
0084 class ExplodedNodeSet;
0085 class ExplodedNode;
0086 class IndirectGotoNodeBuilder;
0087 class MemRegion;
0088 class NodeBuilderContext;
0089 class NodeBuilderWithSinks;
0090 class ProgramState;
0091 class ProgramStateManager;
0092 class RegionAndSymbolInvalidationTraits;
0093 class SymbolManager;
0094 class SwitchNodeBuilder;
0095
0096
0097 struct EvalCallOptions {
0098
0099
0100 bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false;
0101
0102
0103
0104 bool IsArrayCtorOrDtor = false;
0105
0106
0107 bool IsTemporaryCtorOrDtor = false;
0108
0109
0110
0111
0112 bool IsTemporaryLifetimeExtendedViaAggregate = false;
0113
0114
0115
0116
0117
0118
0119 bool IsElidableCtorThatHasNotBeenElided = false;
0120
0121 EvalCallOptions() {}
0122 };
0123
0124 class ExprEngine {
0125 void anchor();
0126
0127 public:
0128
0129 enum InliningModes {
0130
0131 Inline_Regular = 0,
0132
0133
0134 Inline_Minimal = 0x1
0135 };
0136
0137 private:
0138 cross_tu::CrossTranslationUnitContext &CTU;
0139 bool IsCTUEnabled;
0140
0141 AnalysisManager &AMgr;
0142
0143 AnalysisDeclContextManager &AnalysisDeclContexts;
0144
0145 CoreEngine Engine;
0146
0147
0148 ExplodedGraph &G;
0149
0150
0151 ProgramStateManager StateMgr;
0152
0153
0154 SymbolManager &SymMgr;
0155
0156
0157 MemRegionManager &MRMgr;
0158
0159
0160 SValBuilder &svalBuilder;
0161
0162 unsigned int currStmtIdx = 0;
0163 const NodeBuilderContext *currBldrCtx = nullptr;
0164
0165
0166
0167 ObjCNoReturn ObjCNoRet;
0168
0169
0170
0171
0172 PathSensitiveBugReporter BR;
0173
0174
0175
0176 SetOfConstDecls *VisitedCallees;
0177
0178
0179 InliningModes HowToInline;
0180
0181 public:
0182 ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
0183 SetOfConstDecls *VisitedCalleesIn,
0184 FunctionSummariesTy *FS, InliningModes HowToInlineIn);
0185
0186 virtual ~ExprEngine() = default;
0187
0188
0189 bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
0190 assert(L->inTopFrame());
0191 BR.setAnalysisEntryPoint(L->getDecl());
0192 return Engine.ExecuteWorkList(L, Steps, nullptr);
0193 }
0194
0195
0196 ASTContext &getContext() const { return AMgr.getASTContext(); }
0197
0198 AnalysisManager &getAnalysisManager() { return AMgr; }
0199
0200 AnalysisDeclContextManager &getAnalysisDeclContextManager() {
0201 return AMgr.getAnalysisDeclContextManager();
0202 }
0203
0204 CheckerManager &getCheckerManager() const {
0205 return *AMgr.getCheckerManager();
0206 }
0207
0208 SValBuilder &getSValBuilder() { return svalBuilder; }
0209
0210 BugReporter &getBugReporter() { return BR; }
0211
0212 cross_tu::CrossTranslationUnitContext *
0213 getCrossTranslationUnitContext() {
0214 return &CTU;
0215 }
0216
0217 const NodeBuilderContext &getBuilderContext() {
0218 assert(currBldrCtx);
0219 return *currBldrCtx;
0220 }
0221
0222 const Stmt *getStmt() const;
0223
0224 const LocationContext *getRootLocationContext() const {
0225 assert(G.roots_begin() != G.roots_end());
0226 return (*G.roots_begin())->getLocation().getLocationContext();
0227 }
0228
0229 CFGBlock::ConstCFGElementRef getCFGElementRef() const {
0230 const CFGBlock *blockPtr = currBldrCtx ? currBldrCtx->getBlock() : nullptr;
0231 return {blockPtr, currStmtIdx};
0232 }
0233
0234
0235
0236
0237 std::string DumpGraph(bool trim = false, StringRef Filename="");
0238
0239
0240
0241
0242 std::string DumpGraph(ArrayRef<const ExplodedNode *> Nodes,
0243 StringRef Filename = "");
0244
0245
0246 void ViewGraph(bool trim = false);
0247
0248
0249
0250 void ViewGraph(ArrayRef<const ExplodedNode *> Nodes);
0251
0252
0253
0254 ProgramStateRef getInitialState(const LocationContext *InitLoc);
0255
0256 ExplodedGraph &getGraph() { return G; }
0257 const ExplodedGraph &getGraph() const { return G; }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
0285 const Stmt *ReferenceStmt, const LocationContext *LC,
0286 const Stmt *DiagnosticStmt = nullptr,
0287 ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
0288
0289
0290
0291 static const ProgramPointTag *cleanupNodeTag();
0292
0293
0294
0295 void processCFGElement(const CFGElement E, ExplodedNode *Pred,
0296 unsigned StmtIdx, NodeBuilderContext *Ctx);
0297
0298 void ProcessStmt(const Stmt *S, ExplodedNode *Pred);
0299
0300 void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
0301
0302 void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
0303
0304 void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
0305
0306 void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
0307
0308 void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
0309 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0310 void ProcessDeleteDtor(const CFGDeleteDtor D,
0311 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0312 void ProcessBaseDtor(const CFGBaseDtor D,
0313 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0314 void ProcessMemberDtor(const CFGMemberDtor D,
0315 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0316 void ProcessTemporaryDtor(const CFGTemporaryDtor D,
0317 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0318
0319
0320 void processCFGBlockEntrance(const BlockEdge &L,
0321 NodeBuilderWithSinks &nodeBuilder,
0322 ExplodedNode *Pred);
0323
0324
0325
0326
0327
0328 void processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx,
0329 ExplodedNode *Pred, ExplodedNodeSet &Dst,
0330 const CFGBlock *DstT, const CFGBlock *DstF,
0331 std::optional<unsigned> IterationsCompletedInLoop);
0332
0333
0334
0335
0336 void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
0337 NodeBuilderContext &BldCtx,
0338 ExplodedNode *Pred, ExplodedNodeSet &Dst,
0339 const CFGBlock *DstT,
0340 const CFGBlock *DstF);
0341
0342
0343
0344 void processStaticInitializer(const DeclStmt *DS,
0345 NodeBuilderContext& BuilderCtx,
0346 ExplodedNode *Pred,
0347 ExplodedNodeSet &Dst,
0348 const CFGBlock *DstT,
0349 const CFGBlock *DstF);
0350
0351
0352
0353 void processIndirectGoto(IndirectGotoNodeBuilder& builder);
0354
0355
0356
0357 void processSwitch(SwitchNodeBuilder& builder);
0358
0359
0360
0361 void processBeginOfFunction(NodeBuilderContext &BC,
0362 ExplodedNode *Pred, ExplodedNodeSet &Dst,
0363 const BlockEdge &L);
0364
0365
0366
0367 void processEndOfFunction(NodeBuilderContext& BC,
0368 ExplodedNode *Pred,
0369 const ReturnStmt *RS = nullptr);
0370
0371
0372 void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
0373 ExplodedNode *Pred,
0374 ExplodedNodeSet &Dst);
0375
0376
0377 void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
0378 ExplodedNode *Pred);
0379
0380
0381
0382 void processCallExit(ExplodedNode *Pred);
0383
0384
0385 void processEndWorklist();
0386
0387
0388
0389 ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
0390 bool assumption);
0391
0392
0393
0394 ProgramStateRef
0395 processRegionChanges(ProgramStateRef state,
0396 const InvalidatedSymbols *invalidated,
0397 ArrayRef<const MemRegion *> ExplicitRegions,
0398 ArrayRef<const MemRegion *> Regions,
0399 const LocationContext *LCtx,
0400 const CallEvent *Call);
0401
0402 inline ProgramStateRef
0403 processRegionChange(ProgramStateRef state,
0404 const MemRegion* MR,
0405 const LocationContext *LCtx) {
0406 return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
0407 }
0408
0409
0410 void printJson(raw_ostream &Out, ProgramStateRef State,
0411 const LocationContext *LCtx, const char *NL,
0412 unsigned int Space, bool IsDot) const;
0413
0414 ProgramStateManager &getStateManager() { return StateMgr; }
0415
0416 StoreManager &getStoreManager() { return StateMgr.getStoreManager(); }
0417
0418 ConstraintManager &getConstraintManager() {
0419 return StateMgr.getConstraintManager();
0420 }
0421
0422
0423 BasicValueFactory &getBasicVals() {
0424 return StateMgr.getBasicVals();
0425 }
0426
0427 SymbolManager &getSymbolManager() { return SymMgr; }
0428 MemRegionManager &getRegionManager() { return MRMgr; }
0429
0430 DataTag::Factory &getDataTags() { return Engine.getDataTags(); }
0431
0432
0433 bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
0434 bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
0435 bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
0436
0437 const CoreEngine &getCoreEngine() const { return Engine; }
0438
0439 public:
0440
0441
0442 void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
0443
0444
0445 void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred,
0446 ExplodedNodeSet &Dst);
0447
0448
0449 void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex,
0450 ExplodedNode *Pred,
0451 ExplodedNodeSet &Dst);
0452
0453
0454 void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
0455 ExplodedNodeSet &Dst);
0456
0457
0458 void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
0459 ExplodedNodeSet &Dst);
0460
0461
0462 void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
0463 ExplodedNodeSet &Dst);
0464
0465
0466 void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
0467 ExplodedNodeSet &Dst);
0468
0469
0470 void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred,
0471 ExplodedNodeSet &Dst);
0472
0473
0474
0475 void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
0476 ExplodedNodeSet &Dst);
0477
0478
0479 void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
0480 ExplodedNodeSet &Dst);
0481
0482
0483 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
0484 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0485
0486
0487 void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
0488 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0489
0490
0491 void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
0492 ExplodedNodeSet &Dst);
0493
0494
0495 void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
0496 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0497
0498 void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
0499 ExplodedNodeSet &Dst);
0500
0501
0502 void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
0503 ExplodedNodeSet &Dst);
0504
0505
0506 void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
0507 ExplodedNodeSet &Dst);
0508
0509
0510 void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred,
0511 ExplodedNodeSet &Dst);
0512
0513
0514 void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
0515 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0516
0517
0518 void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
0519 ExplodedNodeSet &Dst);
0520
0521
0522
0523 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
0524 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0525
0526 void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
0527 ExplodedNodeSet &Dst);
0528
0529
0530 void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
0531 ExplodedNodeSet &Dst);
0532
0533
0534 void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
0535 ExplodedNodeSet &Dst);
0536
0537
0538 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
0539 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0540
0541
0542 void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
0543 ExplodedNodeSet &Dst);
0544
0545
0546 void VisitIncrementDecrementOperator(const UnaryOperator* U,
0547 ExplodedNode *Pred,
0548 ExplodedNodeSet &Dst);
0549
0550 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
0551 ExplodedNodeSet &PreVisit,
0552 ExplodedNodeSet &Dst);
0553
0554 void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
0555 ExplodedNodeSet &Dst);
0556
0557 void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
0558 ExplodedNodeSet & Dst);
0559
0560 void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
0561 ExplodedNodeSet &Dst);
0562
0563 void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E,
0564 ExplodedNode *Pred, ExplodedNodeSet &Dst);
0565
0566 void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
0567 const Stmt *S, bool IsBaseDtor,
0568 ExplodedNode *Pred, ExplodedNodeSet &Dst,
0569 EvalCallOptions &Options);
0570
0571 void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
0572 ExplodedNode *Pred,
0573 ExplodedNodeSet &Dst);
0574
0575 void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
0576 ExplodedNodeSet &Dst);
0577
0578 void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
0579 ExplodedNodeSet &Dst);
0580
0581
0582 void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
0583 ExplodedNode *Pred,
0584 ExplodedNodeSet &Dst);
0585
0586
0587
0588 void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
0589 const Expr *Ex);
0590
0591 bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const;
0592
0593 static std::pair<const ProgramPointTag *, const ProgramPointTag *>
0594 getEagerlyAssumeBifurcationTags();
0595
0596 ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
0597 const LocationContext *LCtx, QualType T,
0598 QualType ExTy, const CastExpr *CastE,
0599 StmtNodeBuilder &Bldr,
0600 ExplodedNode *Pred);
0601
0602 void handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
0603 StmtNodeBuilder &Bldr);
0604
0605 public:
0606 SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
0607 SVal LHS, SVal RHS, QualType T) {
0608 return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
0609 }
0610
0611
0612 static std::optional<unsigned>
0613 getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
0614 const LocationContext *LCtx);
0615
0616
0617 static std::optional<unsigned>
0618 getPendingArrayDestruction(ProgramStateRef State,
0619 const LocationContext *LCtx);
0620
0621
0622 static std::optional<unsigned>
0623 getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E,
0624 const LocationContext *LCtx);
0625
0626
0627
0628
0629 static std::optional<SVal>
0630 getObjectUnderConstruction(ProgramStateRef State,
0631 const ConstructionContextItem &Item,
0632 const LocationContext *LC);
0633
0634
0635 ProgramStateRef processPointerEscapedOnBind(
0636 ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals,
0637 const LocationContext *LCtx, PointerEscapeKind Kind,
0638 const CallEvent *Call);
0639
0640
0641
0642
0643 ProgramStateRef notifyCheckersOfPointerEscape(
0644 ProgramStateRef State,
0645 const InvalidatedSymbols *Invalidated,
0646 ArrayRef<const MemRegion *> ExplicitRegions,
0647 const CallEvent *Call,
0648 RegionAndSymbolInvalidationTraits &ITraits);
0649
0650 private:
0651
0652
0653 void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
0654 SVal location, SVal Val, bool atDeclInit = false,
0655 const ProgramPoint *PP = nullptr);
0656
0657 ProgramStateRef
0658 processPointerEscapedOnBind(ProgramStateRef State,
0659 SVal Loc, SVal Val,
0660 const LocationContext *LCtx);
0661
0662
0663
0664 ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef<SVal> Vs,
0665 PointerEscapeKind K,
0666 const CallEvent *Call = nullptr) const;
0667
0668 public:
0669
0670
0671
0672
0673
0674
0675 void evalLoad(ExplodedNodeSet &Dst,
0676 const Expr *NodeEx,
0677 const Expr *BoundExpr,
0678 ExplodedNode *Pred,
0679 ProgramStateRef St,
0680 SVal location,
0681 const ProgramPointTag *tag = nullptr,
0682 QualType LoadTy = QualType());
0683
0684
0685
0686 void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
0687 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
0688 const ProgramPointTag *tag = nullptr);
0689
0690
0691
0692 CFGElement getCurrentCFGElement() {
0693 return (*currBldrCtx->getBlock())[currStmtIdx];
0694 }
0695
0696
0697
0698 ProgramStateRef bindReturnValue(const CallEvent &Call,
0699 const LocationContext *LCtx,
0700 ProgramStateRef State);
0701
0702
0703
0704 void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
0705 const CallEvent &Call);
0706
0707
0708 void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
0709 const CallEvent &Call,
0710 const EvalCallOptions &CallOpts = {});
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
0726 const NodeBuilderContext *BldrCtx,
0727 const LocationContext *LCtx,
0728 const ConstructionContext *CC,
0729 EvalCallOptions &CallOpts,
0730 unsigned Idx = 0);
0731
0732
0733
0734
0735
0736
0737 ProgramStateRef updateObjectsUnderConstruction(
0738 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
0739 const ConstructionContext *CC, const EvalCallOptions &CallOpts);
0740
0741
0742
0743 std::pair<ProgramStateRef, SVal> handleConstructionContext(
0744 const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
0745 const LocationContext *LCtx, const ConstructionContext *CC,
0746 EvalCallOptions &CallOpts, unsigned Idx = 0) {
0747
0748 SVal V = computeObjectUnderConstruction(E, State, BldrCtx, LCtx, CC,
0749 CallOpts, Idx);
0750 State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
0751
0752 return std::make_pair(State, V);
0753 }
0754
0755 private:
0756 ProgramStateRef finishArgumentConstruction(ProgramStateRef State,
0757 const CallEvent &Call);
0758 void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
0759 const CallEvent &Call);
0760
0761 void evalLocation(ExplodedNodeSet &Dst,
0762 const Stmt *NodeEx,
0763 const Stmt *BoundEx,
0764 ExplodedNode *Pred,
0765 ProgramStateRef St,
0766 SVal location,
0767 bool isLoad);
0768
0769
0770 void examineStackFrames(const Decl *D, const LocationContext *LCtx,
0771 bool &IsRecursive, unsigned &StackDepth);
0772
0773 enum CallInlinePolicy {
0774 CIP_Allowed,
0775 CIP_DisallowedOnce,
0776 CIP_DisallowedAlways
0777 };
0778
0779
0780
0781 CallInlinePolicy mayInlineCallKind(const CallEvent &Call,
0782 const ExplodedNode *Pred,
0783 AnalyzerOptions &Opts,
0784 const EvalCallOptions &CallOpts);
0785
0786
0787
0788
0789
0790
0791 bool isSmall(AnalysisDeclContext *ADC) const;
0792
0793
0794
0795 bool isLarge(AnalysisDeclContext *ADC) const;
0796
0797
0798
0799 bool isHuge(AnalysisDeclContext *ADC) const;
0800
0801
0802
0803 bool mayInlineDecl(AnalysisDeclContext *ADC) const;
0804
0805
0806 bool shouldInlineCall(const CallEvent &Call, const Decl *D,
0807 const ExplodedNode *Pred,
0808 const EvalCallOptions &CallOpts = {});
0809
0810
0811
0812 bool shouldInlineArrayConstruction(const ProgramStateRef State,
0813 const CXXConstructExpr *CE,
0814 const LocationContext *LCtx);
0815
0816
0817
0818
0819 bool shouldInlineArrayDestruction(uint64_t Size);
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832 std::pair<ProgramStateRef, uint64_t> prepareStateForArrayDestruction(
0833 const ProgramStateRef State, const MemRegion *Region,
0834 const QualType &ElementTy, const LocationContext *LCtx,
0835 SVal *ElementCountVal = nullptr);
0836
0837
0838
0839 bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
0840 const LocationContext *LCtx);
0841
0842 void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
0843 NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
0844
0845 void ctuBifurcate(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
0846 ExplodedNode *Pred, ProgramStateRef State);
0847
0848
0849 bool isSecondPhaseCTU() { return IsCTUEnabled && !Engine.getCTUWorkList(); }
0850
0851
0852
0853 void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
0854 ExplodedNode *Pred, ProgramStateRef State);
0855
0856
0857
0858 void BifurcateCall(const MemRegion *BifurReg,
0859 const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
0860 ExplodedNode *Pred);
0861
0862 bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
0863
0864
0865
0866 void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
0867 const CallEvent &Call);
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 ProgramStateRef createTemporaryRegionIfNeeded(
0880 ProgramStateRef State, const LocationContext *LC,
0881 const Expr *InitWithAdjustments, const Expr *Result = nullptr,
0882 const SubRegion **OutRegionWithAdjustments = nullptr);
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892 static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
0893 QualType &Ty, bool &IsArray, unsigned Idx = 0);
0894
0895
0896
0897 void handleConstructor(const Expr *E, ExplodedNode *Pred,
0898 ExplodedNodeSet &Dst);
0899
0900 public:
0901
0902
0903
0904 [[nodiscard]] static ProgramStateRef
0905 setWhetherHasMoreIteration(ProgramStateRef State,
0906 const ObjCForCollectionStmt *O,
0907 const LocationContext *LC, bool HasMoreIteraton);
0908
0909 [[nodiscard]] static ProgramStateRef
0910 removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O,
0911 const LocationContext *LC);
0912
0913 [[nodiscard]] static bool hasMoreIteration(ProgramStateRef State,
0914 const ObjCForCollectionStmt *O,
0915 const LocationContext *LC);
0916
0917 private:
0918
0919
0920 static ProgramStateRef
0921 setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
0922 const LocationContext *LCtx, unsigned Idx);
0923
0924 static ProgramStateRef
0925 removeIndexOfElementToConstruct(ProgramStateRef State,
0926 const CXXConstructExpr *E,
0927 const LocationContext *LCtx);
0928
0929
0930
0931 static ProgramStateRef setPendingArrayDestruction(ProgramStateRef State,
0932 const LocationContext *LCtx,
0933 unsigned Idx);
0934
0935 static ProgramStateRef
0936 removePendingArrayDestruction(ProgramStateRef State,
0937 const LocationContext *LCtx);
0938
0939
0940 static ProgramStateRef setPendingInitLoop(ProgramStateRef State,
0941 const CXXConstructExpr *E,
0942 const LocationContext *LCtx,
0943 unsigned Idx);
0944
0945 static ProgramStateRef removePendingInitLoop(ProgramStateRef State,
0946 const CXXConstructExpr *E,
0947 const LocationContext *LCtx);
0948
0949 static ProgramStateRef
0950 removeStateTraitsUsedForArrayEvaluation(ProgramStateRef State,
0951 const CXXConstructExpr *E,
0952 const LocationContext *LCtx);
0953
0954
0955
0956
0957
0958
0959
0960
0961 static ProgramStateRef
0962 addObjectUnderConstruction(ProgramStateRef State,
0963 const ConstructionContextItem &Item,
0964 const LocationContext *LC, SVal V);
0965
0966
0967
0968 static ProgramStateRef
0969 finishObjectConstruction(ProgramStateRef State,
0970 const ConstructionContextItem &Item,
0971 const LocationContext *LC);
0972
0973
0974
0975
0976 static ProgramStateRef elideDestructor(ProgramStateRef State,
0977 const CXXBindTemporaryExpr *BTE,
0978 const LocationContext *LC);
0979
0980
0981 static ProgramStateRef
0982 cleanupElidedDestructor(ProgramStateRef State,
0983 const CXXBindTemporaryExpr *BTE,
0984 const LocationContext *LC);
0985
0986
0987
0988
0989 static bool isDestructorElided(ProgramStateRef State,
0990 const CXXBindTemporaryExpr *BTE,
0991 const LocationContext *LC);
0992
0993
0994
0995
0996
0997 static bool areAllObjectsFullyConstructed(ProgramStateRef State,
0998 const LocationContext *FromLC,
0999 const LocationContext *ToLC);
1000 };
1001
1002
1003
1004
1005
1006 struct ReplayWithoutInlining{};
1007 template <>
1008 struct ProgramStateTrait<ReplayWithoutInlining> :
1009 public ProgramStatePartialTrait<const void*> {
1010 static void *GDMIndex();
1011 };
1012
1013 }
1014
1015 }
1016
1017 #endif