ExprEngine.h revision 740d490593e0de8732a697c9f77b90ddd463863b
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The LLVM Compiler Infrastructure 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// License. See LICENSE.TXT for details. 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===// 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// 10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// This file defines a meta-engine for path-sensitive dataflow analysis that 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// is built on CoreEngine, but provides the boilerplate to execute transfer 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// functions and build the ExplodedGraph at the expression level. 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===----------------------------------------------------------------------===// 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef LLVM_CLANG_GR_EXPRENGINE 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define LLVM_CLANG_GR_EXPRENGINE 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/Expr.h" 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/Type.h" 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace clang { 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class AnalysisDeclContextManager; 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXCatchStmt; 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CXXConstructExpr; 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CXXDeleteExpr; 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXNewExpr; 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXTemporaryObjectExpr; 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass CXXThisExpr; 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass MaterializeTemporaryExpr; 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass ObjCAtSynchronizedStmt; 39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass ObjCForCollectionStmt; 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace ento { 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass AnalysisManager; 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass CallEvent; 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass ObjCMessage; 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ExprEngine : public SubEngine { 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AnalysisManager &AMgr; 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AnalysisDeclContextManager &AnalysisDeclContexts; 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CoreEngine Engine; 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// G - the simulation graph. 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExplodedGraph& G; 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch /// StateMgr - Object that manages the data for all created states. 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ProgramStateManager StateMgr; 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /// SymMgr - Object that manages the symbol information. 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SymbolManager& SymMgr; 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /// svalBuilder - SValBuilder object that creates SVals from expressions. 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SValBuilder &svalBuilder; 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /// EntryNode - The immediate predecessor node. 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExplodedNode *EntryNode; 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// CleanedState - The state for EntryNode "cleaned" of all dead 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// variables and symbols (as determined by a liveness analysis). 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProgramStateRef CleanedState; 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// currentStmt - The current block-level statement. 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Stmt *currentStmt; 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unsigned int currentStmtIdx; 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const NodeBuilderContext *currentBuilderContext; 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// Obj-C Class Identifiers. 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) IdentifierInfo* NSExceptionII; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// Obj-C Selectors. 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Selector* NSExceptionInstanceRaiseSelectors; 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Selector RaiseSel; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// Whether or not GC is enabled in this analysis. 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool ObjCGCEnabled; 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// The BugReporter associated with this engine. It is important that 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// this object be placed at the very end of member variables so that its 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// destructor is called before the rest of the ExprEngine is destroyed. 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GRBugReporter BR; 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochpublic: 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExprEngine(AnalysisManager &mgr, bool gcEnabled, 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SetOfConstDecls *VisitedCallees, 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionSummariesTy *FS); 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ~ExprEngine(); 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Returns true if there is still simulation state on the worklist. 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return Engine.ExecuteWorkList(L, Steps, 0); 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch /// Execute the work list with an initial state. Nodes that reaches the exit 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// of the function are added into the Dst set, which represent the exit 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// state of the function call. Returns true if there is still simulation 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// state on the worklist. 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProgramStateRef InitState, 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExplodedNodeSet &Dst) { 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// getContext - Return the ASTContext associated with this analysis. 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASTContext &getContext() const { return AMgr.getASTContext(); } 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual AnalysisManager &getAnalysisManager() { return AMgr; } 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CheckerManager &getCheckerManager() const { 121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return *AMgr.getCheckerManager(); 122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SValBuilder &getSValBuilder() { return svalBuilder; } 125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BugReporter& getBugReporter() { return BR; } 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const NodeBuilderContext &getBuilderContext() { 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) assert(currentBuilderContext); 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return *currentBuilderContext; 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool isObjCGCEnabled() { return ObjCGCEnabled; } 134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const Stmt *getStmt() const; 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void GenerateAutoTransition(ExplodedNode *N); 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void enqueueEndOfPath(ExplodedNodeSet &S); 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void GenerateCallExitNode(ExplodedNode *N); 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// ViewGraph - Visualize the ExplodedGraph created by executing the 142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// simulation. 143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void ViewGraph(bool trim = false); 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void ViewGraph(ExplodedNode** Beg, ExplodedNode** End); 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// getInitialState - Return the initial state used for the root vertex 148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// in the ExplodedGraph. 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ProgramStateRef getInitialState(const LocationContext *InitLoc); 150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedGraph& getGraph() { return G; } 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ExplodedGraph& getGraph() const { return G; } 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// \brief Run the analyzer's garbage collection - remove dead symbols and 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// bindings. 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// 157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// \param Node - The predecessor node, from which the processing should 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// start. 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// \param Out - The returned set of output nodes. 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// \param ReferenceStmt - Run garbage collection using the symbols, 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// which are live before the given statement. 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// \param LC - The location context of the ReferenceStmt. 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// \param DiagnosticStmt - the statement used to associate the diagnostic 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// message, if any warnings should occur while removing the dead (leaks 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// are usually reported here). 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// \param K - In some cases it is possible to use PreStmt kind. (Do 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// not use it unless you know what you are doing.) 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const Stmt *ReferenceStmt, const LocationContext *LC, 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const Stmt *DiagnosticStmt, 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// processCFGElement - Called by CoreEngine. Used to generate new successor 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// nodes by processing the 'effects' of a CFG element. 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void processCFGElement(const CFGElement E, ExplodedNode *Pred, 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) unsigned StmtIdx, NodeBuilderContext *Ctx); 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void ProcessStmt(const CFGStmt S, ExplodedNode *Pred); 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred); 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void ProcessBaseDtor(const CFGBaseDtor D, 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void ProcessMemberDtor(const CFGMemberDtor D, 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void ProcessTemporaryDtor(const CFGTemporaryDtor D, 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Called by CoreEngine when processing the entrance of a CFGBlock. 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void processCFGBlockEntrance(const BlockEdge &L, 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NodeBuilderWithSinks &nodeBuilder); 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// ProcessBranch - Called by CoreEngine. Used to generate successor 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// nodes by processing the 'effects' of a branch condition. 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void processBranch(const Stmt *Condition, const Stmt *Term, 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NodeBuilderContext& BuilderCtx, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExplodedNode *Pred, 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst, 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const CFGBlock *DstT, 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const CFGBlock *DstF); 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// processIndirectGoto - Called by CoreEngine. Used to generate successor 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// nodes by processing the 'effects' of a computed goto jump. 208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void processIndirectGoto(IndirectGotoNodeBuilder& builder); 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// ProcessSwitch - Called by CoreEngine. Used to generate successor 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// nodes by processing the 'effects' of a switch statement. 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void processSwitch(SwitchNodeBuilder& builder); 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// nodes when the control reaches the end of a function. 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void processEndOfFunction(NodeBuilderContext& BC); 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Generate the entry node of the callee. 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void processCallEnter(CallEnter CE, ExplodedNode *Pred); 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Generate the sequence of nodes that simulate the call exit and the post 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// visit for CallExpr. 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void processCallExit(ExplodedNode *Pred); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// Called by CoreEngine when the analysis worklist has terminated. 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void processEndWorklist(bool hasWorkRemaining); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// evalAssume - Callback function invoked by the ConstraintManager when 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// making assumptions about state values. 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// region change should trigger a processRegionChanges update. 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool wantsRegionChangeUpdate(ProgramStateRef state); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// processRegionChanges - Called by ProgramStateManager whenever a change is made 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// to the store. Used to update checkers that track region values. 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProgramStateRef 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) processRegionChanges(ProgramStateRef state, 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StoreManager::InvalidatedSymbols *invalidated, 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ArrayRef<const MemRegion *> ExplicitRegions, 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ArrayRef<const MemRegion *> Regions, 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CallEvent *Call); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// printState - Called by ProgramStateManager to print checker-specific data. 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void printState(raw_ostream &Out, ProgramStateRef State, 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char *NL, const char *Sep); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ProgramStateManager& getStateManager() { return StateMgr; } 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConstraintManager& getConstraintManager() { 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return StateMgr.getConstraintManager(); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // FIXME: Remove when we migrate over to just using SValBuilder. 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BasicValueFactory& getBasicVals() { 259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return StateMgr.getBasicVals(); 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const BasicValueFactory& getBasicVals() const { 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return StateMgr.getBasicVals(); 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // FIXME: Remove when we migrate over to just using ValueManager. 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SymbolManager& getSymbolManager() { return SymMgr; } 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const SymbolManager& getSymbolManager() const { return SymMgr; } 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Functions for external checking of whether we have unfinished work 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); } 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const CoreEngine &getCoreEngine() const { return Engine; } 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)public: 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Visit - Transfer function logic for all statements. Dispatches to 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// other functions that handle specific kinds of statements. 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitArraySubscriptExpr - Transfer function for array accesses. 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitAsmStmt - Transfer function logic for inline asm. 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst); 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitMSAsmStmt - Transfer function logic for MS inline asm. 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitBlockExpr - Transfer function logic for BlockExprs. 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitBinaryOperator - Transfer function logic for binary operators. 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitCall - Transfer function for function calls. 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitCast - Transfer function logic for all casts (implicit and explicit). 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, 308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// VisitDeclStmt - Transfer function logic for DeclStmts. 319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNodeSet &Dst); 328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// VisitLogicalExpr - Transfer function logic for '&&', '||' 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNodeSet &Dst); 332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// VisitMemberExpr - Transfer function for member expressions. 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNodeSet &Dst); 336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// Transfer function logic for ObjCAtSynchronizedStmts. 338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// Transfer function logic for computing the lvalue of an Objective-C ivar. 342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, 343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ExplodedNodeSet &Dst); 344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// VisitObjCForCollectionStmt - Transfer function logic for 346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /// ObjCForCollectionStmt. 347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitObjCMessage(const ObjCMessage &msg, ExplodedNode *Pred, 35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// VisitReturnStmt - Transfer function logic for return statements. 35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// VisitOffsetOfExpr - Transfer function for offsetof. 35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, 35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// VisitUnaryOperator - Transfer function logic for unary operators. 36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// Handle ++ and -- (both pre- and post-increment). 37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitIncrementDecrementOperator(const UnaryOperator* U, 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNode *Pred, 37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ExplodedNodeSet &Dst); 376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExplodedNodeSet & Dst); 379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr, 3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExplodedNode *Pred, ExplodedNodeSet &Dst); 3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest, 3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExplodedNode *Pred, ExplodedNodeSet &Dst); 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void VisitCXXDestructor(const CXXDestructorDecl *DD, 387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const MemRegion *Dest, const Stmt *S, 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExplodedNode *Pred, ExplodedNodeSet &Dst); 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// Create a C++ temporary object for an rvalue. 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNode *Pred, 399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ExplodedNodeSet &Dst); 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// with those assumptions. 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const Expr *Ex); 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::pair<const ProgramPointTag *, const ProgramPointTag*> 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) getEagerlyAssumeTags(); 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SVal evalMinus(SVal X) { 411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X; 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SVal evalComplement(SVal X) { 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X; 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)public: 419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NonLoc L, NonLoc R, QualType T) { 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return svalBuilder.evalBinOpNN(state, op, L, R, T); 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NonLoc L, SVal R, QualType T) { 42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R; 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SVal LHS, SVal RHS, QualType T) { 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochprotected: 436558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMessage &msg, 437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ExplodedNode *Pred, ProgramStateRef state, 438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch bool GenSink); 439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProgramStateRef MarkBranch(ProgramStateRef state, 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Stmt *Terminator, 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const LocationContext *LCtx, 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool branchTaken); 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// evalBind - Handle the semantics of binding a value to a specific location. 446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /// This method is used by evalStore, VisitDeclStmt, and others. 447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, 448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SVal location, SVal Val, bool atDeclInit = false); 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)public: 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // FIXME: 'tag' should be removed, and a LocationContext should be used 452 // instead. 453 // FIXME: Comment on the meaning of the arguments, when 'St' may not 454 // be the same as Pred->state, and when 'location' may not be the 455 // same as state->getLValue(Ex). 456 /// Simulate a read of the result of Ex. 457 void evalLoad(ExplodedNodeSet &Dst, 458 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 459 const Expr *BoundExpr, 460 ExplodedNode *Pred, 461 ProgramStateRef St, 462 SVal location, 463 const ProgramPointTag *tag = 0, 464 QualType LoadTy = QualType()); 465 466 // FIXME: 'tag' should be removed, and a LocationContext should be used 467 // instead. 468 void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, 469 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, 470 const ProgramPointTag *tag = 0); 471private: 472 void evalLoadCommon(ExplodedNodeSet &Dst, 473 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 474 const Expr *BoundEx, 475 ExplodedNode *Pred, 476 ProgramStateRef St, 477 SVal location, 478 const ProgramPointTag *tag, 479 QualType LoadTy); 480 481 // FIXME: 'tag' should be removed, and a LocationContext should be used 482 // instead. 483 void evalLocation(ExplodedNodeSet &Dst, 484 const Stmt *NodeEx, /* This will eventually be a CFGStmt */ 485 const Stmt *BoundEx, 486 ExplodedNode *Pred, 487 ProgramStateRef St, SVal location, 488 const ProgramPointTag *tag, bool isLoad); 489 490 bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred); 491 bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); 492 493 bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); 494}; 495 496/// Traits for storing the call processing policy inside GDM. 497/// The GDM stores the corresponding CallExpr pointer. 498struct ReplayWithoutInlining{}; 499template <> 500struct ProgramStateTrait<ReplayWithoutInlining> : 501 public ProgramStatePartialTrait<void*> { 502 static void *GDMIndex() { static int index = 0; return &index; } 503}; 504 505} // end ento namespace 506 507} // end clang namespace 508 509#endif 510