Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines a meta-engine for path-sensitive dataflow analysis that
  10. //  is built on CoreEngine, but provides the boilerplate to execute transfer
  11. //  functions and build the ExplodedGraph at the expression level.
  12. //
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
  16. #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
  17.  
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/Type.h"
  20. #include "clang/Analysis/CFG.h"
  21. #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
  22. #include "clang/Analysis/ProgramPoint.h"
  23. #include "clang/Basic/LLVM.h"
  24. #include "clang/StaticAnalyzer/Core/CheckerManager.h"
  25. #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
  26. #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
  27. #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
  28. #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
  29. #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
  30. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  31. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
  32. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
  33. #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
  34. #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
  35. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
  36. #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
  37. #include "llvm/ADT/ArrayRef.h"
  38. #include <cassert>
  39. #include <optional>
  40. #include <utility>
  41.  
  42. namespace clang {
  43.  
  44. class AnalysisDeclContextManager;
  45. class AnalyzerOptions;
  46. class ASTContext;
  47. class CFGBlock;
  48. class CFGElement;
  49. class ConstructionContext;
  50. class CXXBindTemporaryExpr;
  51. class CXXCatchStmt;
  52. class CXXConstructExpr;
  53. class CXXDeleteExpr;
  54. class CXXNewExpr;
  55. class CXXThisExpr;
  56. class Decl;
  57. class DeclStmt;
  58. class GCCAsmStmt;
  59. class LambdaExpr;
  60. class LocationContext;
  61. class MaterializeTemporaryExpr;
  62. class MSAsmStmt;
  63. class NamedDecl;
  64. class ObjCAtSynchronizedStmt;
  65. class ObjCForCollectionStmt;
  66. class ObjCIvarRefExpr;
  67. class ObjCMessageExpr;
  68. class ReturnStmt;
  69. class Stmt;
  70.  
  71. namespace cross_tu {
  72.  
  73. class CrossTranslationUnitContext;
  74.  
  75. } // namespace cross_tu
  76.  
  77. namespace ento {
  78.  
  79. class AnalysisManager;
  80. class BasicValueFactory;
  81. class CallEvent;
  82. class CheckerManager;
  83. class ConstraintManager;
  84. class ExplodedNodeSet;
  85. class ExplodedNode;
  86. class IndirectGotoNodeBuilder;
  87. class MemRegion;
  88. struct NodeBuilderContext;
  89. class NodeBuilderWithSinks;
  90. class ProgramState;
  91. class ProgramStateManager;
  92. class RegionAndSymbolInvalidationTraits;
  93. class SymbolManager;
  94. class SwitchNodeBuilder;
  95.  
  96. /// Hints for figuring out of a call should be inlined during evalCall().
  97. struct EvalCallOptions {
  98.   /// This call is a constructor or a destructor for which we do not currently
  99.   /// compute the this-region correctly.
  100.   bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false;
  101.  
  102.   /// This call is a constructor or a destructor for a single element within
  103.   /// an array, a part of array construction or destruction.
  104.   bool IsArrayCtorOrDtor = false;
  105.  
  106.   /// This call is a constructor or a destructor of a temporary value.
  107.   bool IsTemporaryCtorOrDtor = false;
  108.  
  109.   /// This call is a constructor for a temporary that is lifetime-extended
  110.   /// by binding it to a reference-type field within an aggregate,
  111.   /// for example 'A { const C &c; }; A a = { C() };'
  112.   bool IsTemporaryLifetimeExtendedViaAggregate = false;
  113.  
  114.   /// This call is a pre-C++17 elidable constructor that we failed to elide
  115.   /// because we failed to compute the target region into which
  116.   /// this constructor would have been ultimately elided. Analysis that
  117.   /// we perform in this case is still correct but it behaves differently,
  118.   /// as if copy elision is disabled.
  119.   bool IsElidableCtorThatHasNotBeenElided = false;
  120.  
  121.   EvalCallOptions() {}
  122. };
  123.  
  124. class ExprEngine {
  125.   void anchor();
  126.  
  127. public:
  128.   /// The modes of inlining, which override the default analysis-wide settings.
  129.   enum InliningModes {
  130.     /// Follow the default settings for inlining callees.
  131.     Inline_Regular = 0,
  132.  
  133.     /// Do minimal inlining of callees.
  134.     Inline_Minimal = 0x1
  135.   };
  136.  
  137. private:
  138.   cross_tu::CrossTranslationUnitContext &CTU;
  139.   bool IsCTUEnabled;
  140.  
  141.   AnalysisManager &AMgr;
  142.  
  143.   AnalysisDeclContextManager &AnalysisDeclContexts;
  144.  
  145.   CoreEngine Engine;
  146.  
  147.   /// G - the simulation graph.
  148.   ExplodedGraph &G;
  149.  
  150.   /// StateMgr - Object that manages the data for all created states.
  151.   ProgramStateManager StateMgr;
  152.  
  153.   /// SymMgr - Object that manages the symbol information.
  154.   SymbolManager &SymMgr;
  155.  
  156.   /// MRMgr - MemRegionManager object that creates memory regions.
  157.   MemRegionManager &MRMgr;
  158.  
  159.   /// svalBuilder - SValBuilder object that creates SVals from expressions.
  160.   SValBuilder &svalBuilder;
  161.  
  162.   unsigned int currStmtIdx = 0;
  163.   const NodeBuilderContext *currBldrCtx = nullptr;
  164.  
  165.   /// Helper object to determine if an Objective-C message expression
  166.   /// implicitly never returns.
  167.   ObjCNoReturn ObjCNoRet;
  168.  
  169.   /// The BugReporter associated with this engine.  It is important that
  170.   /// this object be placed at the very end of member variables so that its
  171.   /// destructor is called before the rest of the ExprEngine is destroyed.
  172.   PathSensitiveBugReporter BR;
  173.  
  174.   /// The functions which have been analyzed through inlining. This is owned by
  175.   /// AnalysisConsumer. It can be null.
  176.   SetOfConstDecls *VisitedCallees;
  177.  
  178.   /// The flag, which specifies the mode of inlining for the engine.
  179.   InliningModes HowToInline;
  180.  
  181. public:
  182.   ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
  183.              SetOfConstDecls *VisitedCalleesIn,
  184.              FunctionSummariesTy *FS, InliningModes HowToInlineIn);
  185.  
  186.   virtual ~ExprEngine() = default;
  187.  
  188.   /// Returns true if there is still simulation state on the worklist.
  189.   bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
  190.     return Engine.ExecuteWorkList(L, Steps, nullptr);
  191.   }
  192.  
  193.   /// Execute the work list with an initial state. Nodes that reaches the exit
  194.   /// of the function are added into the Dst set, which represent the exit
  195.   /// state of the function call. Returns true if there is still simulation
  196.   /// state on the worklist.
  197.   bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
  198.                                        ProgramStateRef InitState,
  199.                                        ExplodedNodeSet &Dst) {
  200.     return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
  201.   }
  202.  
  203.   /// getContext - Return the ASTContext associated with this analysis.
  204.   ASTContext &getContext() const { return AMgr.getASTContext(); }
  205.  
  206.   AnalysisManager &getAnalysisManager() { return AMgr; }
  207.  
  208.   AnalysisDeclContextManager &getAnalysisDeclContextManager() {
  209.     return AMgr.getAnalysisDeclContextManager();
  210.   }
  211.  
  212.   CheckerManager &getCheckerManager() const {
  213.     return *AMgr.getCheckerManager();
  214.   }
  215.  
  216.   SValBuilder &getSValBuilder() { return svalBuilder; }
  217.  
  218.   BugReporter &getBugReporter() { return BR; }
  219.  
  220.   cross_tu::CrossTranslationUnitContext *
  221.   getCrossTranslationUnitContext() {
  222.     return &CTU;
  223.   }
  224.  
  225.   const NodeBuilderContext &getBuilderContext() {
  226.     assert(currBldrCtx);
  227.     return *currBldrCtx;
  228.   }
  229.  
  230.   const Stmt *getStmt() const;
  231.  
  232.   const LocationContext *getRootLocationContext() const {
  233.     assert(G.roots_begin() != G.roots_end());
  234.     return (*G.roots_begin())->getLocation().getLocationContext();
  235.   }
  236.  
  237.   void GenerateAutoTransition(ExplodedNode *N);
  238.   void enqueueEndOfPath(ExplodedNodeSet &S);
  239.   void GenerateCallExitNode(ExplodedNode *N);
  240.  
  241.  
  242.   /// Dump graph to the specified filename.
  243.   /// If filename is empty, generate a temporary one.
  244.   /// \return The filename the graph is written into.
  245.   std::string DumpGraph(bool trim = false, StringRef Filename="");
  246.  
  247.   /// Dump the graph consisting of the given nodes to a specified filename.
  248.   /// Generate a temporary filename if it's not provided.
  249.   /// \return The filename the graph is written into.
  250.   std::string DumpGraph(ArrayRef<const ExplodedNode *> Nodes,
  251.                         StringRef Filename = "");
  252.  
  253.   /// Visualize the ExplodedGraph created by executing the simulation.
  254.   void ViewGraph(bool trim = false);
  255.  
  256.   /// Visualize a trimmed ExplodedGraph that only contains paths to the given
  257.   /// nodes.
  258.   void ViewGraph(ArrayRef<const ExplodedNode *> Nodes);
  259.  
  260.   /// getInitialState - Return the initial state used for the root vertex
  261.   ///  in the ExplodedGraph.
  262.   ProgramStateRef getInitialState(const LocationContext *InitLoc);
  263.  
  264.   ExplodedGraph &getGraph() { return G; }
  265.   const ExplodedGraph &getGraph() const { return G; }
  266.  
  267.   /// Run the analyzer's garbage collection - remove dead symbols and
  268.   /// bindings from the state.
  269.   ///
  270.   /// Checkers can participate in this process with two callbacks:
  271.   /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
  272.   /// class for more information.
  273.   ///
  274.   /// \param Node The predecessor node, from which the processing should start.
  275.   /// \param Out The returned set of output nodes.
  276.   /// \param ReferenceStmt The statement which is about to be processed.
  277.   ///        Everything needed for this statement should be considered live.
  278.   ///        A null statement means that everything in child LocationContexts
  279.   ///        is dead.
  280.   /// \param LC The location context of the \p ReferenceStmt. A null location
  281.   ///        context means that we have reached the end of analysis and that
  282.   ///        all statements and local variables should be considered dead.
  283.   /// \param DiagnosticStmt Used as a location for any warnings that should
  284.   ///        occur while removing the dead (e.g. leaks). By default, the
  285.   ///        \p ReferenceStmt is used.
  286.   /// \param K Denotes whether this is a pre- or post-statement purge. This
  287.   ///        must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
  288.   ///        entire location context is being cleared, in which case the
  289.   ///        \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
  290.   ///        it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
  291.   ///        and \p ReferenceStmt must be valid (non-null).
  292.   void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
  293.             const Stmt *ReferenceStmt, const LocationContext *LC,
  294.             const Stmt *DiagnosticStmt = nullptr,
  295.             ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
  296.  
  297.   /// processCFGElement - Called by CoreEngine. Used to generate new successor
  298.   ///  nodes by processing the 'effects' of a CFG element.
  299.   void processCFGElement(const CFGElement E, ExplodedNode *Pred,
  300.                          unsigned StmtIdx, NodeBuilderContext *Ctx);
  301.  
  302.   void ProcessStmt(const Stmt *S, ExplodedNode *Pred);
  303.  
  304.   void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
  305.  
  306.   void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
  307.  
  308.   void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
  309.  
  310.   void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
  311.  
  312.   void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
  313.                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
  314.   void ProcessDeleteDtor(const CFGDeleteDtor D,
  315.                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
  316.   void ProcessBaseDtor(const CFGBaseDtor D,
  317.                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
  318.   void ProcessMemberDtor(const CFGMemberDtor D,
  319.                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
  320.   void ProcessTemporaryDtor(const CFGTemporaryDtor D,
  321.                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
  322.  
  323.   /// Called by CoreEngine when processing the entrance of a CFGBlock.
  324.   void processCFGBlockEntrance(const BlockEdge &L,
  325.                                NodeBuilderWithSinks &nodeBuilder,
  326.                                ExplodedNode *Pred);
  327.  
  328.   /// ProcessBranch - Called by CoreEngine.  Used to generate successor
  329.   ///  nodes by processing the 'effects' of a branch condition.
  330.   void processBranch(const Stmt *Condition,
  331.                      NodeBuilderContext& BuilderCtx,
  332.                      ExplodedNode *Pred,
  333.                      ExplodedNodeSet &Dst,
  334.                      const CFGBlock *DstT,
  335.                      const CFGBlock *DstF);
  336.  
  337.   /// Called by CoreEngine.
  338.   /// Used to generate successor nodes for temporary destructors depending
  339.   /// on whether the corresponding constructor was visited.
  340.   void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
  341.                                      NodeBuilderContext &BldCtx,
  342.                                      ExplodedNode *Pred, ExplodedNodeSet &Dst,
  343.                                      const CFGBlock *DstT,
  344.                                      const CFGBlock *DstF);
  345.  
  346.   /// Called by CoreEngine.  Used to processing branching behavior
  347.   /// at static initializers.
  348.   void processStaticInitializer(const DeclStmt *DS,
  349.                                 NodeBuilderContext& BuilderCtx,
  350.                                 ExplodedNode *Pred,
  351.                                 ExplodedNodeSet &Dst,
  352.                                 const CFGBlock *DstT,
  353.                                 const CFGBlock *DstF);
  354.  
  355.   /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
  356.   ///  nodes by processing the 'effects' of a computed goto jump.
  357.   void processIndirectGoto(IndirectGotoNodeBuilder& builder);
  358.  
  359.   /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
  360.   ///  nodes by processing the 'effects' of a switch statement.
  361.   void processSwitch(SwitchNodeBuilder& builder);
  362.  
  363.   /// Called by CoreEngine.  Used to notify checkers that processing a
  364.   /// function has begun. Called for both inlined and top-level functions.
  365.   void processBeginOfFunction(NodeBuilderContext &BC,
  366.                               ExplodedNode *Pred, ExplodedNodeSet &Dst,
  367.                               const BlockEdge &L);
  368.  
  369.   /// Called by CoreEngine.  Used to notify checkers that processing a
  370.   /// function has ended. Called for both inlined and top-level functions.
  371.   void processEndOfFunction(NodeBuilderContext& BC,
  372.                             ExplodedNode *Pred,
  373.                             const ReturnStmt *RS = nullptr);
  374.  
  375.   /// Remove dead bindings/symbols before exiting a function.
  376.   void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
  377.                                  ExplodedNode *Pred,
  378.                                  ExplodedNodeSet &Dst);
  379.  
  380.   /// Generate the entry node of the callee.
  381.   void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
  382.                         ExplodedNode *Pred);
  383.  
  384.   /// Generate the sequence of nodes that simulate the call exit and the post
  385.   /// visit for CallExpr.
  386.   void processCallExit(ExplodedNode *Pred);
  387.  
  388.   /// Called by CoreEngine when the analysis worklist has terminated.
  389.   void processEndWorklist();
  390.  
  391.   /// evalAssume - Callback function invoked by the ConstraintManager when
  392.   ///  making assumptions about state values.
  393.   ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
  394.                                 bool assumption);
  395.  
  396.   /// processRegionChanges - Called by ProgramStateManager whenever a change is made
  397.   ///  to the store. Used to update checkers that track region values.
  398.   ProgramStateRef
  399.   processRegionChanges(ProgramStateRef state,
  400.                        const InvalidatedSymbols *invalidated,
  401.                        ArrayRef<const MemRegion *> ExplicitRegions,
  402.                        ArrayRef<const MemRegion *> Regions,
  403.                        const LocationContext *LCtx,
  404.                        const CallEvent *Call);
  405.  
  406.   inline ProgramStateRef
  407.   processRegionChange(ProgramStateRef state,
  408.                       const MemRegion* MR,
  409.                       const LocationContext *LCtx) {
  410.     return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
  411.   }
  412.  
  413.   /// printJson - Called by ProgramStateManager to print checker-specific data.
  414.   void printJson(raw_ostream &Out, ProgramStateRef State,
  415.                  const LocationContext *LCtx, const char *NL,
  416.                  unsigned int Space, bool IsDot) const;
  417.  
  418.   ProgramStateManager &getStateManager() { return StateMgr; }
  419.  
  420.   StoreManager &getStoreManager() { return StateMgr.getStoreManager(); }
  421.  
  422.   ConstraintManager &getConstraintManager() {
  423.     return StateMgr.getConstraintManager();
  424.   }
  425.  
  426.   // FIXME: Remove when we migrate over to just using SValBuilder.
  427.   BasicValueFactory &getBasicVals() {
  428.     return StateMgr.getBasicVals();
  429.   }
  430.  
  431.   SymbolManager &getSymbolManager() { return SymMgr; }
  432.   MemRegionManager &getRegionManager() { return MRMgr; }
  433.  
  434.   DataTag::Factory &getDataTags() { return Engine.getDataTags(); }
  435.  
  436.   // Functions for external checking of whether we have unfinished work
  437.   bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
  438.   bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
  439.   bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
  440.  
  441.   const CoreEngine &getCoreEngine() const { return Engine; }
  442.  
  443. public:
  444.   /// Visit - Transfer function logic for all statements.  Dispatches to
  445.   ///  other functions that handle specific kinds of statements.
  446.   void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
  447.  
  448.   /// VisitArrayInitLoopExpr - Transfer function for array init loop.
  449.   void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred,
  450.                               ExplodedNodeSet &Dst);
  451.  
  452.   /// VisitArraySubscriptExpr - Transfer function for array accesses.
  453.   void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex,
  454.                                ExplodedNode *Pred,
  455.                                ExplodedNodeSet &Dst);
  456.  
  457.   /// VisitGCCAsmStmt - Transfer function logic for inline asm.
  458.   void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
  459.                        ExplodedNodeSet &Dst);
  460.  
  461.   /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
  462.   void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
  463.                       ExplodedNodeSet &Dst);
  464.  
  465.   /// VisitBlockExpr - Transfer function logic for BlockExprs.
  466.   void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
  467.                       ExplodedNodeSet &Dst);
  468.  
  469.   /// VisitLambdaExpr - Transfer function logic for LambdaExprs.
  470.   void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
  471.                        ExplodedNodeSet &Dst);
  472.  
  473.   /// VisitBinaryOperator - Transfer function logic for binary operators.
  474.   void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred,
  475.                            ExplodedNodeSet &Dst);
  476.  
  477.  
  478.   /// VisitCall - Transfer function for function calls.
  479.   void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
  480.                      ExplodedNodeSet &Dst);
  481.  
  482.   /// VisitCast - Transfer function logic for all casts (implicit and explicit).
  483.   void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
  484.                  ExplodedNodeSet &Dst);
  485.  
  486.   /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
  487.   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
  488.                                 ExplodedNode *Pred, ExplodedNodeSet &Dst);
  489.  
  490.   /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
  491.   void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
  492.                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
  493.  
  494.   /// VisitDeclStmt - Transfer function logic for DeclStmts.
  495.   void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
  496.                      ExplodedNodeSet &Dst);
  497.  
  498.   /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
  499.   void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
  500.                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
  501.  
  502.   void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
  503.                          ExplodedNodeSet &Dst);
  504.  
  505.   /// VisitLogicalExpr - Transfer function logic for '&&', '||'
  506.   void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
  507.                         ExplodedNodeSet &Dst);
  508.  
  509.   /// VisitMemberExpr - Transfer function for member expressions.
  510.   void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
  511.                        ExplodedNodeSet &Dst);
  512.  
  513.   /// VisitAtomicExpr - Transfer function for builtin atomic expressions
  514.   void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred,
  515.                        ExplodedNodeSet &Dst);
  516.  
  517.   /// Transfer function logic for ObjCAtSynchronizedStmts.
  518.   void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
  519.                                    ExplodedNode *Pred, ExplodedNodeSet &Dst);
  520.  
  521.   /// Transfer function logic for computing the lvalue of an Objective-C ivar.
  522.   void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
  523.                                 ExplodedNodeSet &Dst);
  524.  
  525.   /// VisitObjCForCollectionStmt - Transfer function logic for
  526.   ///  ObjCForCollectionStmt.
  527.   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
  528.                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
  529.  
  530.   void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
  531.                         ExplodedNodeSet &Dst);
  532.  
  533.   /// VisitReturnStmt - Transfer function logic for return statements.
  534.   void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
  535.                        ExplodedNodeSet &Dst);
  536.  
  537.   /// VisitOffsetOfExpr - Transfer function for offsetof.
  538.   void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
  539.                          ExplodedNodeSet &Dst);
  540.  
  541.   /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
  542.   void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
  543.                                      ExplodedNode *Pred, ExplodedNodeSet &Dst);
  544.  
  545.   /// VisitUnaryOperator - Transfer function logic for unary operators.
  546.   void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
  547.                           ExplodedNodeSet &Dst);
  548.  
  549.   /// Handle ++ and -- (both pre- and post-increment).
  550.   void VisitIncrementDecrementOperator(const UnaryOperator* U,
  551.                                        ExplodedNode *Pred,
  552.                                        ExplodedNodeSet &Dst);
  553.  
  554.   void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
  555.                                  ExplodedNodeSet &PreVisit,
  556.                                  ExplodedNodeSet &Dst);
  557.  
  558.   void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
  559.                          ExplodedNodeSet &Dst);
  560.  
  561.   void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
  562.                         ExplodedNodeSet & Dst);
  563.  
  564.   void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
  565.                              ExplodedNodeSet &Dst);
  566.  
  567.   void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E,
  568.                                      ExplodedNode *Pred, ExplodedNodeSet &Dst);
  569.  
  570.   void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
  571.                           const Stmt *S, bool IsBaseDtor,
  572.                           ExplodedNode *Pred, ExplodedNodeSet &Dst,
  573.                           EvalCallOptions &Options);
  574.  
  575.   void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
  576.                                 ExplodedNode *Pred,
  577.                                 ExplodedNodeSet &Dst);
  578.  
  579.   void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
  580.                        ExplodedNodeSet &Dst);
  581.  
  582.   void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
  583.                           ExplodedNodeSet &Dst);
  584.  
  585.   /// Create a C++ temporary object for an rvalue.
  586.   void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
  587.                                 ExplodedNode *Pred,
  588.                                 ExplodedNodeSet &Dst);
  589.  
  590.   /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
  591.   ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
  592.   ///  with those assumptions.
  593.   void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
  594.                          const Expr *Ex);
  595.  
  596.   static std::pair<const ProgramPointTag *, const ProgramPointTag *>
  597.     geteagerlyAssumeBinOpBifurcationTags();
  598.  
  599.   ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
  600.                                       const LocationContext *LCtx, QualType T,
  601.                                       QualType ExTy, const CastExpr *CastE,
  602.                                       StmtNodeBuilder &Bldr,
  603.                                       ExplodedNode *Pred);
  604.  
  605.   ProgramStateRef handleLVectorSplat(ProgramStateRef state,
  606.                                      const LocationContext *LCtx,
  607.                                      const CastExpr *CastE,
  608.                                      StmtNodeBuilder &Bldr,
  609.                                      ExplodedNode *Pred);
  610.  
  611.   void handleUOExtension(ExplodedNodeSet::iterator I,
  612.                          const UnaryOperator* U,
  613.                          StmtNodeBuilder &Bldr);
  614.  
  615. public:
  616.   SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
  617.                  SVal LHS, SVal RHS, QualType T) {
  618.     return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
  619.   }
  620.  
  621.   /// Retreives which element is being constructed in a non-POD type array.
  622.   static std::optional<unsigned>
  623.   getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
  624.                                const LocationContext *LCtx);
  625.  
  626.   /// Retreives which element is being destructed in a non-POD type array.
  627.   static std::optional<unsigned>
  628.   getPendingArrayDestruction(ProgramStateRef State,
  629.                              const LocationContext *LCtx);
  630.  
  631.   /// Retreives the size of the array in the pending ArrayInitLoopExpr.
  632.   static std::optional<unsigned>
  633.   getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E,
  634.                      const LocationContext *LCtx);
  635.  
  636.   /// By looking at a certain item that may be potentially part of an object's
  637.   /// ConstructionContext, retrieve such object's location. A particular
  638.   /// statement can be transparently passed as \p Item in most cases.
  639.   static std::optional<SVal>
  640.   getObjectUnderConstruction(ProgramStateRef State,
  641.                              const ConstructionContextItem &Item,
  642.                              const LocationContext *LC);
  643.  
  644.   /// Call PointerEscape callback when a value escapes as a result of bind.
  645.   ProgramStateRef processPointerEscapedOnBind(
  646.       ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals,
  647.       const LocationContext *LCtx, PointerEscapeKind Kind,
  648.       const CallEvent *Call);
  649.  
  650.   /// Call PointerEscape callback when a value escapes as a result of
  651.   /// region invalidation.
  652.   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
  653.   ProgramStateRef notifyCheckersOfPointerEscape(
  654.                            ProgramStateRef State,
  655.                            const InvalidatedSymbols *Invalidated,
  656.                            ArrayRef<const MemRegion *> ExplicitRegions,
  657.                            const CallEvent *Call,
  658.                            RegionAndSymbolInvalidationTraits &ITraits);
  659.  
  660. private:
  661.   /// evalBind - Handle the semantics of binding a value to a specific location.
  662.   ///  This method is used by evalStore, VisitDeclStmt, and others.
  663.   void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
  664.                 SVal location, SVal Val, bool atDeclInit = false,
  665.                 const ProgramPoint *PP = nullptr);
  666.  
  667.   ProgramStateRef
  668.   processPointerEscapedOnBind(ProgramStateRef State,
  669.                               SVal Loc, SVal Val,
  670.                               const LocationContext *LCtx);
  671.  
  672.   /// A simple wrapper when you only need to notify checkers of pointer-escape
  673.   /// of some values.
  674.   ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef<SVal> Vs,
  675.                                PointerEscapeKind K,
  676.                                const CallEvent *Call = nullptr) const;
  677.  
  678. public:
  679.   // FIXME: 'tag' should be removed, and a LocationContext should be used
  680.   // instead.
  681.   // FIXME: Comment on the meaning of the arguments, when 'St' may not
  682.   // be the same as Pred->state, and when 'location' may not be the
  683.   // same as state->getLValue(Ex).
  684.   /// Simulate a read of the result of Ex.
  685.   void evalLoad(ExplodedNodeSet &Dst,
  686.                 const Expr *NodeEx,  /* Eventually will be a CFGStmt */
  687.                 const Expr *BoundExpr,
  688.                 ExplodedNode *Pred,
  689.                 ProgramStateRef St,
  690.                 SVal location,
  691.                 const ProgramPointTag *tag = nullptr,
  692.                 QualType LoadTy = QualType());
  693.  
  694.   // FIXME: 'tag' should be removed, and a LocationContext should be used
  695.   // instead.
  696.   void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
  697.                  ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
  698.                  const ProgramPointTag *tag = nullptr);
  699.  
  700.   /// Return the CFG element corresponding to the worklist element
  701.   /// that is currently being processed by ExprEngine.
  702.   CFGElement getCurrentCFGElement() {
  703.     return (*currBldrCtx->getBlock())[currStmtIdx];
  704.   }
  705.  
  706.   /// Create a new state in which the call return value is binded to the
  707.   /// call origin expression.
  708.   ProgramStateRef bindReturnValue(const CallEvent &Call,
  709.                                   const LocationContext *LCtx,
  710.                                   ProgramStateRef State);
  711.  
  712.   /// Evaluate a call, running pre- and post-call checkers and allowing checkers
  713.   /// to be responsible for handling the evaluation of the call itself.
  714.   void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
  715.                 const CallEvent &Call);
  716.  
  717.   /// Default implementation of call evaluation.
  718.   void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
  719.                        const CallEvent &Call,
  720.                        const EvalCallOptions &CallOpts = {});
  721.  
  722.   /// Find location of the object that is being constructed by a given
  723.   /// constructor. This should ideally always succeed but due to not being
  724.   /// fully implemented it sometimes indicates that it failed via its
  725.   /// out-parameter CallOpts; in such cases a fake temporary region is
  726.   /// returned, which is better than nothing but does not represent
  727.   /// the actual behavior of the program. The Idx parameter is used if we
  728.   /// construct an array of objects. In that case it points to the index
  729.   /// of the continuous memory region.
  730.   /// E.g.:
  731.   /// For `int arr[4]` this index can be 0,1,2,3.
  732.   /// For `int arr2[3][3]` this index can be 0,1,...,7,8.
  733.   /// A multi-dimensional array is also a continuous memory location in a
  734.   /// row major order, so for arr[0][0] Idx is 0 and for arr[2][2] Idx is 8.
  735.   SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
  736.                                       const NodeBuilderContext *BldrCtx,
  737.                                       const LocationContext *LCtx,
  738.                                       const ConstructionContext *CC,
  739.                                       EvalCallOptions &CallOpts,
  740.                                       unsigned Idx = 0);
  741.  
  742.   /// Update the program state with all the path-sensitive information
  743.   /// that's necessary to perform construction of an object with a given
  744.   /// syntactic construction context. V and CallOpts have to be obtained from
  745.   /// computeObjectUnderConstruction() invoked with the same set of
  746.   /// the remaining arguments (E, State, LCtx, CC).
  747.   ProgramStateRef updateObjectsUnderConstruction(
  748.       SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
  749.       const ConstructionContext *CC, const EvalCallOptions &CallOpts);
  750.  
  751.   /// A convenient wrapper around computeObjectUnderConstruction
  752.   /// and updateObjectsUnderConstruction.
  753.   std::pair<ProgramStateRef, SVal> handleConstructionContext(
  754.       const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
  755.       const LocationContext *LCtx, const ConstructionContext *CC,
  756.       EvalCallOptions &CallOpts, unsigned Idx = 0) {
  757.  
  758.     SVal V = computeObjectUnderConstruction(E, State, BldrCtx, LCtx, CC,
  759.                                             CallOpts, Idx);
  760.     State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
  761.  
  762.     return std::make_pair(State, V);
  763.   }
  764.  
  765. private:
  766.   ProgramStateRef finishArgumentConstruction(ProgramStateRef State,
  767.                                              const CallEvent &Call);
  768.   void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
  769.                                   const CallEvent &Call);
  770.  
  771.   void evalLoadCommon(ExplodedNodeSet &Dst,
  772.                       const Expr *NodeEx,  /* Eventually will be a CFGStmt */
  773.                       const Expr *BoundEx,
  774.                       ExplodedNode *Pred,
  775.                       ProgramStateRef St,
  776.                       SVal location,
  777.                       const ProgramPointTag *tag,
  778.                       QualType LoadTy);
  779.  
  780.   void evalLocation(ExplodedNodeSet &Dst,
  781.                     const Stmt *NodeEx, /* This will eventually be a CFGStmt */
  782.                     const Stmt *BoundEx,
  783.                     ExplodedNode *Pred,
  784.                     ProgramStateRef St,
  785.                     SVal location,
  786.                     bool isLoad);
  787.  
  788.   /// Count the stack depth and determine if the call is recursive.
  789.   void examineStackFrames(const Decl *D, const LocationContext *LCtx,
  790.                           bool &IsRecursive, unsigned &StackDepth);
  791.  
  792.   enum CallInlinePolicy {
  793.     CIP_Allowed,
  794.     CIP_DisallowedOnce,
  795.     CIP_DisallowedAlways
  796.   };
  797.  
  798.   /// See if a particular call should be inlined, by only looking
  799.   /// at the call event and the current state of analysis.
  800.   CallInlinePolicy mayInlineCallKind(const CallEvent &Call,
  801.                                      const ExplodedNode *Pred,
  802.                                      AnalyzerOptions &Opts,
  803.                                      const EvalCallOptions &CallOpts);
  804.  
  805.   /// See if the given AnalysisDeclContext is built for a function that we
  806.   /// should always inline simply because it's small enough.
  807.   /// Apart from "small" functions, we also have "large" functions
  808.   /// (cf. isLarge()), some of which are huge (cf. isHuge()), and we classify
  809.   /// the remaining functions as "medium".
  810.   bool isSmall(AnalysisDeclContext *ADC) const;
  811.  
  812.   /// See if the given AnalysisDeclContext is built for a function that we
  813.   /// should inline carefully because it looks pretty large.
  814.   bool isLarge(AnalysisDeclContext *ADC) const;
  815.  
  816.   /// See if the given AnalysisDeclContext is built for a function that we
  817.   /// should never inline because it's legit gigantic.
  818.   bool isHuge(AnalysisDeclContext *ADC) const;
  819.  
  820.   /// See if the given AnalysisDeclContext is built for a function that we
  821.   /// should inline, just by looking at the declaration of the function.
  822.   bool mayInlineDecl(AnalysisDeclContext *ADC) const;
  823.  
  824.   /// Checks our policies and decides weither the given call should be inlined.
  825.   bool shouldInlineCall(const CallEvent &Call, const Decl *D,
  826.                         const ExplodedNode *Pred,
  827.                         const EvalCallOptions &CallOpts = {});
  828.  
  829.   /// Checks whether our policies allow us to inline a non-POD type array
  830.   /// construction.
  831.   bool shouldInlineArrayConstruction(const ProgramStateRef State,
  832.                                      const CXXConstructExpr *CE,
  833.                                      const LocationContext *LCtx);
  834.  
  835.   /// Checks whether our policies allow us to inline a non-POD type array
  836.   /// destruction.
  837.   /// \param Size The size of the array.
  838.   bool shouldInlineArrayDestruction(uint64_t Size);
  839.  
  840.   /// Prepares the program state for array destruction. If no error happens
  841.   /// the function binds a 'PendingArrayDestruction' entry to the state, which
  842.   /// it returns along with the index. If any error happens (we fail to read
  843.   /// the size, the index would be -1, etc.) the function will return the
  844.   /// original state along with an index of 0. The actual element count of the
  845.   /// array can be accessed by the optional 'ElementCountVal' parameter. \param
  846.   /// State The program state. \param Region The memory region where the array
  847.   /// is stored. \param ElementTy The type an element in the array. \param LCty
  848.   /// The location context. \param ElementCountVal A pointer to an optional
  849.   /// SVal. If specified, the size of the array will be returned in it. It can
  850.   /// be Unknown.
  851.   std::pair<ProgramStateRef, uint64_t> prepareStateForArrayDestruction(
  852.       const ProgramStateRef State, const MemRegion *Region,
  853.       const QualType &ElementTy, const LocationContext *LCtx,
  854.       SVal *ElementCountVal = nullptr);
  855.  
  856.   /// Checks whether we construct an array of non-POD type, and decides if the
  857.   /// constructor should be inkoved once again.
  858.   bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
  859.                             const LocationContext *LCtx);
  860.  
  861.   void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
  862.                   NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
  863.  
  864.   void ctuBifurcate(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
  865.                     ExplodedNode *Pred, ProgramStateRef State);
  866.  
  867.   /// Returns true if the CTU analysis is running its second phase.
  868.   bool isSecondPhaseCTU() { return IsCTUEnabled && !Engine.getCTUWorkList(); }
  869.  
  870.   /// Conservatively evaluate call by invalidating regions and binding
  871.   /// a conjured return value.
  872.   void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
  873.                             ExplodedNode *Pred, ProgramStateRef State);
  874.  
  875.   /// Either inline or process the call conservatively (or both), based
  876.   /// on DynamicDispatchBifurcation data.
  877.   void BifurcateCall(const MemRegion *BifurReg,
  878.                      const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
  879.                      ExplodedNode *Pred);
  880.  
  881.   bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
  882.  
  883.   /// Models a trivial copy or move constructor or trivial assignment operator
  884.   /// call with a simple bind.
  885.   void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
  886.                           const CallEvent &Call);
  887.  
  888.   /// If the value of the given expression \p InitWithAdjustments is a NonLoc,
  889.   /// copy it into a new temporary object region, and replace the value of the
  890.   /// expression with that.
  891.   ///
  892.   /// If \p Result is provided, the new region will be bound to this expression
  893.   /// instead of \p InitWithAdjustments.
  894.   ///
  895.   /// Returns the temporary region with adjustments into the optional
  896.   /// OutRegionWithAdjustments out-parameter if a new region was indeed needed,
  897.   /// otherwise sets it to nullptr.
  898.   ProgramStateRef createTemporaryRegionIfNeeded(
  899.       ProgramStateRef State, const LocationContext *LC,
  900.       const Expr *InitWithAdjustments, const Expr *Result = nullptr,
  901.       const SubRegion **OutRegionWithAdjustments = nullptr);
  902.  
  903.   /// Returns a region representing the `Idx`th element of a (possibly
  904.   /// multi-dimensional) array, for the purposes of element construction or
  905.   /// destruction.
  906.   ///
  907.   /// On return, \p Ty will be set to the base type of the array.
  908.   ///
  909.   /// If the type is not an array type at all, the original value is returned.
  910.   /// Otherwise the "IsArray" flag is set.
  911.   static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
  912.                                 QualType &Ty, bool &IsArray, unsigned Idx = 0);
  913.  
  914.   /// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
  915.   /// block to find the constructor expression that directly constructed into
  916.   /// the storage for this statement. Returns null if the constructor for this
  917.   /// statement created a temporary object region rather than directly
  918.   /// constructing into an existing region.
  919.   const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
  920.  
  921.   /// Common code that handles either a CXXConstructExpr or a
  922.   /// CXXInheritedCtorInitExpr.
  923.   void handleConstructor(const Expr *E, ExplodedNode *Pred,
  924.                          ExplodedNodeSet &Dst);
  925.  
  926. public:
  927.   /// Note whether this loop has any more iteratios to model. These methods are
  928.   /// essentially an interface for a GDM trait. Further reading in
  929.   /// ExprEngine::VisitObjCForCollectionStmt().
  930.   [[nodiscard]] static ProgramStateRef
  931.   setWhetherHasMoreIteration(ProgramStateRef State,
  932.                              const ObjCForCollectionStmt *O,
  933.                              const LocationContext *LC, bool HasMoreIteraton);
  934.  
  935.   [[nodiscard]] static ProgramStateRef
  936.   removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O,
  937.                        const LocationContext *LC);
  938.  
  939.   [[nodiscard]] static bool hasMoreIteration(ProgramStateRef State,
  940.                                              const ObjCForCollectionStmt *O,
  941.                                              const LocationContext *LC);
  942.  
  943. private:
  944.   /// Assuming we construct an array of non-POD types, this method allows us
  945.   /// to store which element is to be constructed next.
  946.   static ProgramStateRef
  947.   setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
  948.                                const LocationContext *LCtx, unsigned Idx);
  949.  
  950.   static ProgramStateRef
  951.   removeIndexOfElementToConstruct(ProgramStateRef State,
  952.                                   const CXXConstructExpr *E,
  953.                                   const LocationContext *LCtx);
  954.  
  955.   /// Assuming we destruct an array of non-POD types, this method allows us
  956.   /// to store which element is to be destructed next.
  957.   static ProgramStateRef setPendingArrayDestruction(ProgramStateRef State,
  958.                                                     const LocationContext *LCtx,
  959.                                                     unsigned Idx);
  960.  
  961.   static ProgramStateRef
  962.   removePendingArrayDestruction(ProgramStateRef State,
  963.                                 const LocationContext *LCtx);
  964.  
  965.   /// Sets the size of the array in a pending ArrayInitLoopExpr.
  966.   static ProgramStateRef setPendingInitLoop(ProgramStateRef State,
  967.                                             const CXXConstructExpr *E,
  968.                                             const LocationContext *LCtx,
  969.                                             unsigned Idx);
  970.  
  971.   static ProgramStateRef removePendingInitLoop(ProgramStateRef State,
  972.                                                const CXXConstructExpr *E,
  973.                                                const LocationContext *LCtx);
  974.  
  975.   static ProgramStateRef
  976.   removeStateTraitsUsedForArrayEvaluation(ProgramStateRef State,
  977.                                           const CXXConstructExpr *E,
  978.                                           const LocationContext *LCtx);
  979.  
  980.   /// Store the location of a C++ object corresponding to a statement
  981.   /// until the statement is actually encountered. For example, if a DeclStmt
  982.   /// has CXXConstructExpr as its initializer, the object would be considered
  983.   /// to be "under construction" between CXXConstructExpr and DeclStmt.
  984.   /// This allows, among other things, to keep bindings to variable's fields
  985.   /// made within the constructor alive until its declaration actually
  986.   /// goes into scope.
  987.   static ProgramStateRef
  988.   addObjectUnderConstruction(ProgramStateRef State,
  989.                              const ConstructionContextItem &Item,
  990.                              const LocationContext *LC, SVal V);
  991.  
  992.   /// Mark the object sa fully constructed, cleaning up the state trait
  993.   /// that tracks objects under construction.
  994.   static ProgramStateRef
  995.   finishObjectConstruction(ProgramStateRef State,
  996.                            const ConstructionContextItem &Item,
  997.                            const LocationContext *LC);
  998.  
  999.   /// If the given expression corresponds to a temporary that was used for
  1000.   /// passing into an elidable copy/move constructor and that constructor
  1001.   /// was actually elided, track that we also need to elide the destructor.
  1002.   static ProgramStateRef elideDestructor(ProgramStateRef State,
  1003.                                          const CXXBindTemporaryExpr *BTE,
  1004.                                          const LocationContext *LC);
  1005.  
  1006.   /// Stop tracking the destructor that corresponds to an elided constructor.
  1007.   static ProgramStateRef
  1008.   cleanupElidedDestructor(ProgramStateRef State,
  1009.                           const CXXBindTemporaryExpr *BTE,
  1010.                           const LocationContext *LC);
  1011.  
  1012.   /// Returns true if the given expression corresponds to a temporary that
  1013.   /// was constructed for passing into an elidable copy/move constructor
  1014.   /// and that constructor was actually elided.
  1015.   static bool isDestructorElided(ProgramStateRef State,
  1016.                                  const CXXBindTemporaryExpr *BTE,
  1017.                                  const LocationContext *LC);
  1018.  
  1019.   /// Check if all objects under construction have been fully constructed
  1020.   /// for the given context range (including FromLC, not including ToLC).
  1021.   /// This is useful for assertions. Also checks if elided destructors
  1022.   /// were cleaned up.
  1023.   static bool areAllObjectsFullyConstructed(ProgramStateRef State,
  1024.                                             const LocationContext *FromLC,
  1025.                                             const LocationContext *ToLC);
  1026. };
  1027.  
  1028. /// Traits for storing the call processing policy inside GDM.
  1029. /// The GDM stores the corresponding CallExpr pointer.
  1030. // FIXME: This does not use the nice trait macros because it must be accessible
  1031. // from multiple translation units.
  1032. struct ReplayWithoutInlining{};
  1033. template <>
  1034. struct ProgramStateTrait<ReplayWithoutInlining> :
  1035.   public ProgramStatePartialTrait<const void*> {
  1036.   static void *GDMIndex();
  1037. };
  1038.  
  1039. } // namespace ento
  1040.  
  1041. } // namespace clang
  1042.  
  1043. #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
  1044.