Home | History | Annotate | Download | only in PathSensitive
      1 //== SubEngine.h - Interface of the subengine of CoreEngine --------*- C++ -*-//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the interface of a subengine of the CoreEngine.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
     14 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
     15 
     16 #include "clang/Analysis/ProgramPoint.h"
     17 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     18 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
     19 
     20 namespace clang {
     21 
     22 class CFGBlock;
     23 class CFGElement;
     24 class LocationContext;
     25 class Stmt;
     26 
     27 namespace ento {
     28 
     29 struct NodeBuilderContext;
     30 class AnalysisManager;
     31 class ExplodedNodeSet;
     32 class ExplodedNode;
     33 class ProgramState;
     34 class ProgramStateManager;
     35 class BlockCounter;
     36 class BranchNodeBuilder;
     37 class IndirectGotoNodeBuilder;
     38 class SwitchNodeBuilder;
     39 class EndOfFunctionNodeBuilder;
     40 class NodeBuilderWithSinks;
     41 class MemRegion;
     42 
     43 class SubEngine {
     44   virtual void anchor();
     45 public:
     46   virtual ~SubEngine() {}
     47 
     48   virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
     49 
     50   virtual AnalysisManager &getAnalysisManager() = 0;
     51 
     52   virtual ProgramStateManager &getStateManager() = 0;
     53 
     54   /// Called by CoreEngine. Used to generate new successor
     55   /// nodes by processing the 'effects' of a block-level statement.
     56   virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
     57                                  unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
     58 
     59   /// Called by CoreEngine when it starts processing a CFGBlock.  The
     60   /// SubEngine is expected to populate dstNodes with new nodes representing
     61   /// updated analysis state, or generate no nodes at all if it doesn't.
     62   virtual void processCFGBlockEntrance(const BlockEdge &L,
     63                                        NodeBuilderWithSinks &nodeBuilder,
     64                                        ExplodedNode *Pred) = 0;
     65 
     66   /// Called by CoreEngine.  Used to generate successor
     67   ///  nodes by processing the 'effects' of a branch condition.
     68   virtual void processBranch(const Stmt *Condition, const Stmt *Term,
     69                              NodeBuilderContext& BuilderCtx,
     70                              ExplodedNode *Pred,
     71                              ExplodedNodeSet &Dst,
     72                              const CFGBlock *DstT,
     73                              const CFGBlock *DstF) = 0;
     74 
     75   /// Called by CoreEngine.
     76   /// Used to generate successor nodes for temporary destructors depending
     77   /// on whether the corresponding constructor was visited.
     78   virtual void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
     79                                              NodeBuilderContext &BldCtx,
     80                                              ExplodedNode *Pred,
     81                                              ExplodedNodeSet &Dst,
     82                                              const CFGBlock *DstT,
     83                                              const CFGBlock *DstF) = 0;
     84 
     85   /// Called by CoreEngine.  Used to processing branching behavior
     86   /// at static initializers.
     87   virtual void processStaticInitializer(const DeclStmt *DS,
     88                                         NodeBuilderContext& BuilderCtx,
     89                                         ExplodedNode *Pred,
     90                                         ExplodedNodeSet &Dst,
     91                                         const CFGBlock *DstT,
     92                                         const CFGBlock *DstF) = 0;
     93 
     94   /// Called by CoreEngine.  Used to generate successor
     95   /// nodes by processing the 'effects' of a computed goto jump.
     96   virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
     97 
     98   /// Called by CoreEngine.  Used to generate successor
     99   /// nodes by processing the 'effects' of a switch statement.
    100   virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
    101 
    102   /// Called by CoreEngine.  Used to notify checkers that processing a
    103   /// function has begun. Called for both inlined and and top-level functions.
    104   virtual void processBeginOfFunction(NodeBuilderContext &BC,
    105                                       ExplodedNode *Pred,
    106                                       ExplodedNodeSet &Dst,
    107                                       const BlockEdge &L) = 0;
    108 
    109   /// Called by CoreEngine.  Used to notify checkers that processing a
    110   /// function has ended. Called for both inlined and and top-level functions.
    111   virtual void processEndOfFunction(NodeBuilderContext& BC,
    112                                     ExplodedNode *Pred,
    113                                     const ReturnStmt *RS = nullptr) = 0;
    114 
    115   // Generate the entry node of the callee.
    116   virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
    117                                 ExplodedNode *Pred) = 0;
    118 
    119   // Generate the first post callsite node.
    120   virtual void processCallExit(ExplodedNode *Pred) = 0;
    121 
    122   /// Called by ConstraintManager. Used to call checker-specific
    123   /// logic for handling assumptions on symbolic values.
    124   virtual ProgramStateRef processAssume(ProgramStateRef state,
    125                                        SVal cond, bool assumption) = 0;
    126 
    127   /// processRegionChanges - Called by ProgramStateManager whenever a change is
    128   /// made to the store. Used to update checkers that track region values.
    129   virtual ProgramStateRef
    130   processRegionChanges(ProgramStateRef state,
    131                        const InvalidatedSymbols *invalidated,
    132                        ArrayRef<const MemRegion *> ExplicitRegions,
    133                        ArrayRef<const MemRegion *> Regions,
    134                        const LocationContext *LCtx,
    135                        const CallEvent *Call) = 0;
    136 
    137 
    138   inline ProgramStateRef
    139   processRegionChange(ProgramStateRef state,
    140                       const MemRegion* MR,
    141                       const LocationContext *LCtx) {
    142     return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
    143   }
    144 
    145   virtual ProgramStateRef
    146   processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
    147 
    148   virtual ProgramStateRef
    149   notifyCheckersOfPointerEscape(ProgramStateRef State,
    150                            const InvalidatedSymbols *Invalidated,
    151                            ArrayRef<const MemRegion *> ExplicitRegions,
    152                            ArrayRef<const MemRegion *> Regions,
    153                            const CallEvent *Call,
    154                            RegionAndSymbolInvalidationTraits &HTraits) = 0;
    155 
    156   /// printState - Called by ProgramStateManager to print checker-specific data.
    157   virtual void printState(raw_ostream &Out, ProgramStateRef State,
    158                           const char *NL, const char *Sep) = 0;
    159 
    160   /// Called by CoreEngine when the analysis worklist is either empty or the
    161   //  maximum number of analysis steps have been reached.
    162   virtual void processEndWorklist(bool hasWorkRemaining) = 0;
    163 };
    164 
    165 } // end GR namespace
    166 
    167 } // end clang namespace
    168 
    169 #endif
    170