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