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