clang API Documentation
00001 //===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a meta-engine for path-sensitive dataflow analysis that 00011 // is built on CoreEngine, but provides the boilerplate to execute transfer 00012 // functions and build the ExplodedGraph at the expression level. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H 00017 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H 00018 00019 #include "clang/AST/Expr.h" 00020 #include "clang/AST/Type.h" 00021 #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" 00022 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 00023 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 00024 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 00025 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 00026 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 00027 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 00028 00029 namespace clang { 00030 00031 class AnalysisDeclContextManager; 00032 class CXXCatchStmt; 00033 class CXXConstructExpr; 00034 class CXXDeleteExpr; 00035 class CXXNewExpr; 00036 class CXXTemporaryObjectExpr; 00037 class CXXThisExpr; 00038 class MaterializeTemporaryExpr; 00039 class ObjCAtSynchronizedStmt; 00040 class ObjCForCollectionStmt; 00041 00042 namespace ento { 00043 00044 class AnalysisManager; 00045 class CallEvent; 00046 class CXXConstructorCall; 00047 00048 class ExprEngine : public SubEngine { 00049 public: 00050 /// The modes of inlining, which override the default analysis-wide settings. 00051 enum InliningModes { 00052 /// Follow the default settings for inlining callees. 00053 Inline_Regular = 0, 00054 /// Do minimal inlining of callees. 00055 Inline_Minimal = 0x1 00056 }; 00057 00058 private: 00059 AnalysisManager &AMgr; 00060 00061 AnalysisDeclContextManager &AnalysisDeclContexts; 00062 00063 CoreEngine Engine; 00064 00065 /// G - the simulation graph. 00066 ExplodedGraph& G; 00067 00068 /// StateMgr - Object that manages the data for all created states. 00069 ProgramStateManager StateMgr; 00070 00071 /// SymMgr - Object that manages the symbol information. 00072 SymbolManager& SymMgr; 00073 00074 /// svalBuilder - SValBuilder object that creates SVals from expressions. 00075 SValBuilder &svalBuilder; 00076 00077 unsigned int currStmtIdx; 00078 const NodeBuilderContext *currBldrCtx; 00079 00080 /// Helper object to determine if an Objective-C message expression 00081 /// implicitly never returns. 00082 ObjCNoReturn ObjCNoRet; 00083 00084 /// Whether or not GC is enabled in this analysis. 00085 bool ObjCGCEnabled; 00086 00087 /// The BugReporter associated with this engine. It is important that 00088 /// this object be placed at the very end of member variables so that its 00089 /// destructor is called before the rest of the ExprEngine is destroyed. 00090 GRBugReporter BR; 00091 00092 /// The functions which have been analyzed through inlining. This is owned by 00093 /// AnalysisConsumer. It can be null. 00094 SetOfConstDecls *VisitedCallees; 00095 00096 /// The flag, which specifies the mode of inlining for the engine. 00097 InliningModes HowToInline; 00098 00099 public: 00100 ExprEngine(AnalysisManager &mgr, bool gcEnabled, 00101 SetOfConstDecls *VisitedCalleesIn, 00102 FunctionSummariesTy *FS, 00103 InliningModes HowToInlineIn); 00104 00105 ~ExprEngine(); 00106 00107 /// Returns true if there is still simulation state on the worklist. 00108 bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 00109 return Engine.ExecuteWorkList(L, Steps, nullptr); 00110 } 00111 00112 /// Execute the work list with an initial state. Nodes that reaches the exit 00113 /// of the function are added into the Dst set, which represent the exit 00114 /// state of the function call. Returns true if there is still simulation 00115 /// state on the worklist. 00116 bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 00117 ProgramStateRef InitState, 00118 ExplodedNodeSet &Dst) { 00119 return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 00120 } 00121 00122 /// getContext - Return the ASTContext associated with this analysis. 00123 ASTContext &getContext() const { return AMgr.getASTContext(); } 00124 00125 AnalysisManager &getAnalysisManager() override { return AMgr; } 00126 00127 CheckerManager &getCheckerManager() const { 00128 return *AMgr.getCheckerManager(); 00129 } 00130 00131 SValBuilder &getSValBuilder() { return svalBuilder; } 00132 00133 BugReporter& getBugReporter() { return BR; } 00134 00135 const NodeBuilderContext &getBuilderContext() { 00136 assert(currBldrCtx); 00137 return *currBldrCtx; 00138 } 00139 00140 bool isObjCGCEnabled() { return ObjCGCEnabled; } 00141 00142 const Stmt *getStmt() const; 00143 00144 void GenerateAutoTransition(ExplodedNode *N); 00145 void enqueueEndOfPath(ExplodedNodeSet &S); 00146 void GenerateCallExitNode(ExplodedNode *N); 00147 00148 /// Visualize the ExplodedGraph created by executing the simulation. 00149 void ViewGraph(bool trim = false); 00150 00151 /// Visualize a trimmed ExplodedGraph that only contains paths to the given 00152 /// nodes. 00153 void ViewGraph(ArrayRef<const ExplodedNode*> Nodes); 00154 00155 /// getInitialState - Return the initial state used for the root vertex 00156 /// in the ExplodedGraph. 00157 ProgramStateRef getInitialState(const LocationContext *InitLoc) override; 00158 00159 ExplodedGraph& getGraph() { return G; } 00160 const ExplodedGraph& getGraph() const { return G; } 00161 00162 /// \brief Run the analyzer's garbage collection - remove dead symbols and 00163 /// bindings from the state. 00164 /// 00165 /// Checkers can participate in this process with two callbacks: 00166 /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation 00167 /// class for more information. 00168 /// 00169 /// \param Node The predecessor node, from which the processing should start. 00170 /// \param Out The returned set of output nodes. 00171 /// \param ReferenceStmt The statement which is about to be processed. 00172 /// Everything needed for this statement should be considered live. 00173 /// A null statement means that everything in child LocationContexts 00174 /// is dead. 00175 /// \param LC The location context of the \p ReferenceStmt. A null location 00176 /// context means that we have reached the end of analysis and that 00177 /// all statements and local variables should be considered dead. 00178 /// \param DiagnosticStmt Used as a location for any warnings that should 00179 /// occur while removing the dead (e.g. leaks). By default, the 00180 /// \p ReferenceStmt is used. 00181 /// \param K Denotes whether this is a pre- or post-statement purge. This 00182 /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an 00183 /// entire location context is being cleared, in which case the 00184 /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, 00185 /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) 00186 /// and \p ReferenceStmt must be valid (non-null). 00187 void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, 00188 const Stmt *ReferenceStmt, const LocationContext *LC, 00189 const Stmt *DiagnosticStmt = nullptr, 00190 ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); 00191 00192 /// processCFGElement - Called by CoreEngine. Used to generate new successor 00193 /// nodes by processing the 'effects' of a CFG element. 00194 void processCFGElement(const CFGElement E, ExplodedNode *Pred, 00195 unsigned StmtIdx, NodeBuilderContext *Ctx) override; 00196 00197 void ProcessStmt(const CFGStmt S, ExplodedNode *Pred); 00198 00199 void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); 00200 00201 void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred); 00202 00203 void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred); 00204 00205 void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 00206 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00207 void ProcessDeleteDtor(const CFGDeleteDtor D, 00208 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00209 void ProcessBaseDtor(const CFGBaseDtor D, 00210 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00211 void ProcessMemberDtor(const CFGMemberDtor D, 00212 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00213 void ProcessTemporaryDtor(const CFGTemporaryDtor D, 00214 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00215 00216 /// Called by CoreEngine when processing the entrance of a CFGBlock. 00217 void processCFGBlockEntrance(const BlockEdge &L, 00218 NodeBuilderWithSinks &nodeBuilder, 00219 ExplodedNode *Pred) override; 00220 00221 /// ProcessBranch - Called by CoreEngine. Used to generate successor 00222 /// nodes by processing the 'effects' of a branch condition. 00223 void processBranch(const Stmt *Condition, const Stmt *Term, 00224 NodeBuilderContext& BuilderCtx, 00225 ExplodedNode *Pred, 00226 ExplodedNodeSet &Dst, 00227 const CFGBlock *DstT, 00228 const CFGBlock *DstF) override; 00229 00230 /// Called by CoreEngine. 00231 /// Used to generate successor nodes for temporary destructors depending 00232 /// on whether the corresponding constructor was visited. 00233 void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, 00234 NodeBuilderContext &BldCtx, 00235 ExplodedNode *Pred, ExplodedNodeSet &Dst, 00236 const CFGBlock *DstT, 00237 const CFGBlock *DstF) override; 00238 00239 /// Called by CoreEngine. Used to processing branching behavior 00240 /// at static initalizers. 00241 void processStaticInitializer(const DeclStmt *DS, 00242 NodeBuilderContext& BuilderCtx, 00243 ExplodedNode *Pred, 00244 ExplodedNodeSet &Dst, 00245 const CFGBlock *DstT, 00246 const CFGBlock *DstF) override; 00247 00248 /// processIndirectGoto - Called by CoreEngine. Used to generate successor 00249 /// nodes by processing the 'effects' of a computed goto jump. 00250 void processIndirectGoto(IndirectGotoNodeBuilder& builder) override; 00251 00252 /// ProcessSwitch - Called by CoreEngine. Used to generate successor 00253 /// nodes by processing the 'effects' of a switch statement. 00254 void processSwitch(SwitchNodeBuilder& builder) override; 00255 00256 /// Called by CoreEngine. Used to generate end-of-path 00257 /// nodes when the control reaches the end of a function. 00258 void processEndOfFunction(NodeBuilderContext& BC, 00259 ExplodedNode *Pred) override; 00260 00261 /// Remove dead bindings/symbols before exiting a function. 00262 void removeDeadOnEndOfFunction(NodeBuilderContext& BC, 00263 ExplodedNode *Pred, 00264 ExplodedNodeSet &Dst); 00265 00266 /// Generate the entry node of the callee. 00267 void processCallEnter(CallEnter CE, ExplodedNode *Pred) override; 00268 00269 /// Generate the sequence of nodes that simulate the call exit and the post 00270 /// visit for CallExpr. 00271 void processCallExit(ExplodedNode *Pred) override; 00272 00273 /// Called by CoreEngine when the analysis worklist has terminated. 00274 void processEndWorklist(bool hasWorkRemaining) override; 00275 00276 /// evalAssume - Callback function invoked by the ConstraintManager when 00277 /// making assumptions about state values. 00278 ProgramStateRef processAssume(ProgramStateRef state, SVal cond, 00279 bool assumption) override; 00280 00281 /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 00282 /// region change should trigger a processRegionChanges update. 00283 bool wantsRegionChangeUpdate(ProgramStateRef state) override; 00284 00285 /// processRegionChanges - Called by ProgramStateManager whenever a change is made 00286 /// to the store. Used to update checkers that track region values. 00287 ProgramStateRef 00288 processRegionChanges(ProgramStateRef state, 00289 const InvalidatedSymbols *invalidated, 00290 ArrayRef<const MemRegion *> ExplicitRegions, 00291 ArrayRef<const MemRegion *> Regions, 00292 const CallEvent *Call) override; 00293 00294 /// printState - Called by ProgramStateManager to print checker-specific data. 00295 void printState(raw_ostream &Out, ProgramStateRef State, 00296 const char *NL, const char *Sep) override; 00297 00298 ProgramStateManager& getStateManager() override { return StateMgr; } 00299 00300 StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 00301 00302 ConstraintManager& getConstraintManager() { 00303 return StateMgr.getConstraintManager(); 00304 } 00305 00306 // FIXME: Remove when we migrate over to just using SValBuilder. 00307 BasicValueFactory& getBasicVals() { 00308 return StateMgr.getBasicVals(); 00309 } 00310 00311 // FIXME: Remove when we migrate over to just using ValueManager. 00312 SymbolManager& getSymbolManager() { return SymMgr; } 00313 const SymbolManager& getSymbolManager() const { return SymMgr; } 00314 00315 // Functions for external checking of whether we have unfinished work 00316 bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } 00317 bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 00318 bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); } 00319 00320 const CoreEngine &getCoreEngine() const { return Engine; } 00321 00322 public: 00323 /// Visit - Transfer function logic for all statements. Dispatches to 00324 /// other functions that handle specific kinds of statements. 00325 void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); 00326 00327 /// VisitArraySubscriptExpr - Transfer function for array accesses. 00328 void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, 00329 ExplodedNode *Pred, 00330 ExplodedNodeSet &Dst); 00331 00332 /// VisitGCCAsmStmt - Transfer function logic for inline asm. 00333 void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 00334 ExplodedNodeSet &Dst); 00335 00336 /// VisitMSAsmStmt - Transfer function logic for MS inline asm. 00337 void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 00338 ExplodedNodeSet &Dst); 00339 00340 /// VisitBlockExpr - Transfer function logic for BlockExprs. 00341 void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 00342 ExplodedNodeSet &Dst); 00343 00344 /// VisitBinaryOperator - Transfer function logic for binary operators. 00345 void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 00346 ExplodedNodeSet &Dst); 00347 00348 00349 /// VisitCall - Transfer function for function calls. 00350 void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, 00351 ExplodedNodeSet &Dst); 00352 00353 /// VisitCast - Transfer function logic for all casts (implicit and explicit). 00354 void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, 00355 ExplodedNodeSet &Dst); 00356 00357 /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. 00358 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 00359 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00360 00361 /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 00362 void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, 00363 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00364 00365 /// VisitDeclStmt - Transfer function logic for DeclStmts. 00366 void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 00367 ExplodedNodeSet &Dst); 00368 00369 /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 00370 void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 00371 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00372 00373 void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, 00374 ExplodedNodeSet &Dst); 00375 00376 /// VisitLogicalExpr - Transfer function logic for '&&', '||' 00377 void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 00378 ExplodedNodeSet &Dst); 00379 00380 /// VisitMemberExpr - Transfer function for member expressions. 00381 void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 00382 ExplodedNodeSet &Dst); 00383 00384 /// Transfer function logic for ObjCAtSynchronizedStmts. 00385 void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 00386 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00387 00388 /// Transfer function logic for computing the lvalue of an Objective-C ivar. 00389 void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, 00390 ExplodedNodeSet &Dst); 00391 00392 /// VisitObjCForCollectionStmt - Transfer function logic for 00393 /// ObjCForCollectionStmt. 00394 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 00395 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00396 00397 void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, 00398 ExplodedNodeSet &Dst); 00399 00400 /// VisitReturnStmt - Transfer function logic for return statements. 00401 void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 00402 ExplodedNodeSet &Dst); 00403 00404 /// VisitOffsetOfExpr - Transfer function for offsetof. 00405 void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, 00406 ExplodedNodeSet &Dst); 00407 00408 /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. 00409 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 00410 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00411 00412 /// VisitUnaryOperator - Transfer function logic for unary operators. 00413 void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 00414 ExplodedNodeSet &Dst); 00415 00416 /// Handle ++ and -- (both pre- and post-increment). 00417 void VisitIncrementDecrementOperator(const UnaryOperator* U, 00418 ExplodedNode *Pred, 00419 ExplodedNodeSet &Dst); 00420 00421 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, 00422 ExplodedNodeSet &PreVisit, 00423 ExplodedNodeSet &Dst); 00424 00425 void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 00426 ExplodedNodeSet &Dst); 00427 00428 void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 00429 ExplodedNodeSet & Dst); 00430 00431 void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, 00432 ExplodedNodeSet &Dst); 00433 00434 void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, 00435 const Stmt *S, bool IsBaseDtor, 00436 ExplodedNode *Pred, ExplodedNodeSet &Dst); 00437 00438 void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, 00439 ExplodedNode *Pred, 00440 ExplodedNodeSet &Dst); 00441 00442 void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 00443 ExplodedNodeSet &Dst); 00444 00445 void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 00446 ExplodedNodeSet &Dst); 00447 00448 /// Create a C++ temporary object for an rvalue. 00449 void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 00450 ExplodedNode *Pred, 00451 ExplodedNodeSet &Dst); 00452 00453 /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic 00454 /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 00455 /// with those assumptions. 00456 void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 00457 const Expr *Ex); 00458 00459 std::pair<const ProgramPointTag *, const ProgramPointTag*> 00460 geteagerlyAssumeBinOpBifurcationTags(); 00461 00462 SVal evalMinus(SVal X) { 00463 return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X; 00464 } 00465 00466 SVal evalComplement(SVal X) { 00467 return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X; 00468 } 00469 00470 public: 00471 00472 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 00473 NonLoc L, NonLoc R, QualType T) { 00474 return svalBuilder.evalBinOpNN(state, op, L, R, T); 00475 } 00476 00477 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 00478 NonLoc L, SVal R, QualType T) { 00479 return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L, 00480 R.castAs<NonLoc>(), T) : R; 00481 } 00482 00483 SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, 00484 SVal LHS, SVal RHS, QualType T) { 00485 return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 00486 } 00487 00488 protected: 00489 /// evalBind - Handle the semantics of binding a value to a specific location. 00490 /// This method is used by evalStore, VisitDeclStmt, and others. 00491 void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, 00492 SVal location, SVal Val, bool atDeclInit = false, 00493 const ProgramPoint *PP = nullptr); 00494 00495 /// Call PointerEscape callback when a value escapes as a result of bind. 00496 ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, 00497 SVal Loc, SVal Val) override; 00498 /// Call PointerEscape callback when a value escapes as a result of 00499 /// region invalidation. 00500 /// \param[in] ITraits Specifies invalidation traits for regions/symbols. 00501 ProgramStateRef notifyCheckersOfPointerEscape( 00502 ProgramStateRef State, 00503 const InvalidatedSymbols *Invalidated, 00504 ArrayRef<const MemRegion *> ExplicitRegions, 00505 ArrayRef<const MemRegion *> Regions, 00506 const CallEvent *Call, 00507 RegionAndSymbolInvalidationTraits &ITraits) override; 00508 00509 public: 00510 // FIXME: 'tag' should be removed, and a LocationContext should be used 00511 // instead. 00512 // FIXME: Comment on the meaning of the arguments, when 'St' may not 00513 // be the same as Pred->state, and when 'location' may not be the 00514 // same as state->getLValue(Ex). 00515 /// Simulate a read of the result of Ex. 00516 void evalLoad(ExplodedNodeSet &Dst, 00517 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 00518 const Expr *BoundExpr, 00519 ExplodedNode *Pred, 00520 ProgramStateRef St, 00521 SVal location, 00522 const ProgramPointTag *tag = nullptr, 00523 QualType LoadTy = QualType()); 00524 00525 // FIXME: 'tag' should be removed, and a LocationContext should be used 00526 // instead. 00527 void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, 00528 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, 00529 const ProgramPointTag *tag = nullptr); 00530 00531 /// \brief Create a new state in which the call return value is binded to the 00532 /// call origin expression. 00533 ProgramStateRef bindReturnValue(const CallEvent &Call, 00534 const LocationContext *LCtx, 00535 ProgramStateRef State); 00536 00537 /// Evaluate a call, running pre- and post-call checks and allowing checkers 00538 /// to be responsible for handling the evaluation of the call itself. 00539 void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, 00540 const CallEvent &Call); 00541 00542 /// \brief Default implementation of call evaluation. 00543 void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, 00544 const CallEvent &Call); 00545 private: 00546 void evalLoadCommon(ExplodedNodeSet &Dst, 00547 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 00548 const Expr *BoundEx, 00549 ExplodedNode *Pred, 00550 ProgramStateRef St, 00551 SVal location, 00552 const ProgramPointTag *tag, 00553 QualType LoadTy); 00554 00555 // FIXME: 'tag' should be removed, and a LocationContext should be used 00556 // instead. 00557 void evalLocation(ExplodedNodeSet &Dst, 00558 const Stmt *NodeEx, /* This will eventually be a CFGStmt */ 00559 const Stmt *BoundEx, 00560 ExplodedNode *Pred, 00561 ProgramStateRef St, SVal location, 00562 const ProgramPointTag *tag, bool isLoad); 00563 00564 /// Count the stack depth and determine if the call is recursive. 00565 void examineStackFrames(const Decl *D, const LocationContext *LCtx, 00566 bool &IsRecursive, unsigned &StackDepth); 00567 00568 /// Checks our policies and decides weither the given call should be inlined. 00569 bool shouldInlineCall(const CallEvent &Call, const Decl *D, 00570 const ExplodedNode *Pred); 00571 00572 bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 00573 ExplodedNode *Pred, ProgramStateRef State); 00574 00575 /// \brief Conservatively evaluate call by invalidating regions and binding 00576 /// a conjured return value. 00577 void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, 00578 ExplodedNode *Pred, ProgramStateRef State); 00579 00580 /// \brief Either inline or process the call conservatively (or both), based 00581 /// on DynamicDispatchBifurcation data. 00582 void BifurcateCall(const MemRegion *BifurReg, 00583 const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 00584 ExplodedNode *Pred); 00585 00586 bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); 00587 00588 /// Models a trivial copy or move constructor or trivial assignment operator 00589 /// call with a simple bind. 00590 void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 00591 const CallEvent &Call); 00592 00593 /// If the value of the given expression is a NonLoc, copy it into a new 00594 /// temporary object region, and replace the value of the expression with 00595 /// that. 00596 /// 00597 /// If \p ResultE is provided, the new region will be bound to this expression 00598 /// instead of \p E. 00599 ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, 00600 const LocationContext *LC, 00601 const Expr *E, 00602 const Expr *ResultE = nullptr); 00603 }; 00604 00605 /// Traits for storing the call processing policy inside GDM. 00606 /// The GDM stores the corresponding CallExpr pointer. 00607 // FIXME: This does not use the nice trait macros because it must be accessible 00608 // from multiple translation units. 00609 struct ReplayWithoutInlining{}; 00610 template <> 00611 struct ProgramStateTrait<ReplayWithoutInlining> : 00612 public ProgramStatePartialTrait<const void*> { 00613 static void *GDMIndex() { static int index = 0; return &index; } 00614 }; 00615 00616 } // end ento namespace 00617 00618 } // end clang namespace 00619 00620 #endif