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: ~SubEngine()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 initalizers. 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) = 0; 113 114 // Generate the entry node of the callee. 115 virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE, 116 ExplodedNode *Pred) = 0; 117 118 // Generate the first post callsite node. 119 virtual void processCallExit(ExplodedNode *Pred) = 0; 120 121 /// Called by ConstraintManager. Used to call checker-specific 122 /// logic for handling assumptions on symbolic values. 123 virtual ProgramStateRef processAssume(ProgramStateRef state, 124 SVal cond, bool assumption) = 0; 125 126 /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 127 /// region change should trigger a processRegionChanges update. 128 virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0; 129 130 /// processRegionChanges - Called by ProgramStateManager whenever a change is 131 /// made to the store. Used to update checkers that track region values. 132 virtual ProgramStateRef 133 processRegionChanges(ProgramStateRef state, 134 const InvalidatedSymbols *invalidated, 135 ArrayRef<const MemRegion *> ExplicitRegions, 136 ArrayRef<const MemRegion *> Regions, 137 const CallEvent *Call) = 0; 138 139 140 inline ProgramStateRef processRegionChange(ProgramStateRef state,const MemRegion * MR)141 processRegionChange(ProgramStateRef state, 142 const MemRegion* MR) { 143 return processRegionChanges(state, nullptr, MR, MR, nullptr); 144 } 145 146 virtual ProgramStateRef 147 processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0; 148 149 virtual ProgramStateRef 150 notifyCheckersOfPointerEscape(ProgramStateRef State, 151 const InvalidatedSymbols *Invalidated, 152 ArrayRef<const MemRegion *> ExplicitRegions, 153 ArrayRef<const MemRegion *> Regions, 154 const CallEvent *Call, 155 RegionAndSymbolInvalidationTraits &HTraits) = 0; 156 157 /// printState - Called by ProgramStateManager to print checker-specific data. 158 virtual void printState(raw_ostream &Out, ProgramStateRef State, 159 const char *NL, const char *Sep) = 0; 160 161 /// Called by CoreEngine when the analysis worklist is either empty or the 162 // maximum number of analysis steps have been reached. 163 virtual void processEndWorklist(bool hasWorkRemaining) = 0; 164 }; 165 166 } // end GR namespace 167 168 } // end clang namespace 169 170 #endif 171