1218887Sdim//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// This file defines a meta-engine for path-sensitive dataflow analysis that 11218887Sdim// is built on CoreEngine, but provides the boilerplate to execute transfer 12218887Sdim// functions and build the ExplodedGraph at the expression level. 13218887Sdim// 14218887Sdim//===----------------------------------------------------------------------===// 15218887Sdim 16218887Sdim#ifndef LLVM_CLANG_GR_EXPRENGINE 17218887Sdim#define LLVM_CLANG_GR_EXPRENGINE 18218887Sdim 19249423Sdim#include "clang/AST/Expr.h" 20249423Sdim#include "clang/AST/Type.h" 21243830Sdim#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" 22249423Sdim#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 23218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 24218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 25226633Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 26234353Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 27249423Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 28218887Sdim 29218887Sdimnamespace clang { 30218887Sdim 31234353Sdimclass AnalysisDeclContextManager; 32234353Sdimclass CXXCatchStmt; 33234353Sdimclass CXXConstructExpr; 34234353Sdimclass CXXDeleteExpr; 35234353Sdimclass CXXNewExpr; 36234353Sdimclass CXXTemporaryObjectExpr; 37234353Sdimclass CXXThisExpr; 38234353Sdimclass MaterializeTemporaryExpr; 39234353Sdimclass ObjCAtSynchronizedStmt; 40218887Sdimclass ObjCForCollectionStmt; 41234353Sdim 42218887Sdimnamespace ento { 43218887Sdim 44218887Sdimclass AnalysisManager; 45239462Sdimclass CallEvent; 46239462Sdimclass SimpleCall; 47249423Sdimclass CXXConstructorCall; 48218887Sdim 49218887Sdimclass ExprEngine : public SubEngine { 50249423Sdimpublic: 51249423Sdim /// The modes of inlining, which override the default analysis-wide settings. 52249423Sdim enum InliningModes { 53249423Sdim /// Follow the default settings for inlining callees. 54249423Sdim Inline_Regular = 0, 55249423Sdim /// Do minimal inlining of callees. 56249423Sdim Inline_Minimal = 0x1 57249423Sdim }; 58249423Sdim 59249423Sdimprivate: 60218887Sdim AnalysisManager &AMgr; 61234353Sdim 62234353Sdim AnalysisDeclContextManager &AnalysisDeclContexts; 63218887Sdim 64218887Sdim CoreEngine Engine; 65218887Sdim 66218887Sdim /// G - the simulation graph. 67218887Sdim ExplodedGraph& G; 68218887Sdim 69218887Sdim /// StateMgr - Object that manages the data for all created states. 70226633Sdim ProgramStateManager StateMgr; 71218887Sdim 72218887Sdim /// SymMgr - Object that manages the symbol information. 73218887Sdim SymbolManager& SymMgr; 74218887Sdim 75218887Sdim /// svalBuilder - SValBuilder object that creates SVals from expressions. 76218887Sdim SValBuilder &svalBuilder; 77218887Sdim 78243830Sdim unsigned int currStmtIdx; 79243830Sdim const NodeBuilderContext *currBldrCtx; 80226633Sdim 81243830Sdim /// Helper object to determine if an Objective-C message expression 82243830Sdim /// implicitly never returns. 83243830Sdim ObjCNoReturn ObjCNoRet; 84243830Sdim 85226633Sdim /// Whether or not GC is enabled in this analysis. 86226633Sdim bool ObjCGCEnabled; 87218887Sdim 88218887Sdim /// The BugReporter associated with this engine. It is important that 89218887Sdim /// this object be placed at the very end of member variables so that its 90218887Sdim /// destructor is called before the rest of the ExprEngine is destroyed. 91218887Sdim GRBugReporter BR; 92218887Sdim 93243830Sdim /// The functions which have been analyzed through inlining. This is owned by 94243830Sdim /// AnalysisConsumer. It can be null. 95243830Sdim SetOfConstDecls *VisitedCallees; 96243830Sdim 97249423Sdim /// The flag, which specifies the mode of inlining for the engine. 98249423Sdim InliningModes HowToInline; 99249423Sdim 100218887Sdimpublic: 101234353Sdim ExprEngine(AnalysisManager &mgr, bool gcEnabled, 102243830Sdim SetOfConstDecls *VisitedCalleesIn, 103249423Sdim FunctionSummariesTy *FS, 104249423Sdim InliningModes HowToInlineIn); 105218887Sdim 106218887Sdim ~ExprEngine(); 107218887Sdim 108234353Sdim /// Returns true if there is still simulation state on the worklist. 109234353Sdim bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 110234353Sdim return Engine.ExecuteWorkList(L, Steps, 0); 111218887Sdim } 112218887Sdim 113218887Sdim /// Execute the work list with an initial state. Nodes that reaches the exit 114218887Sdim /// of the function are added into the Dst set, which represent the exit 115234353Sdim /// state of the function call. Returns true if there is still simulation 116234353Sdim /// state on the worklist. 117234353Sdim bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 118234353Sdim ProgramStateRef InitState, 119218887Sdim ExplodedNodeSet &Dst) { 120234353Sdim return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 121218887Sdim } 122218887Sdim 123218887Sdim /// getContext - Return the ASTContext associated with this analysis. 124226633Sdim ASTContext &getContext() const { return AMgr.getASTContext(); } 125218887Sdim 126218887Sdim virtual AnalysisManager &getAnalysisManager() { return AMgr; } 127218887Sdim 128219077Sdim CheckerManager &getCheckerManager() const { 129219077Sdim return *AMgr.getCheckerManager(); 130219077Sdim } 131219077Sdim 132218887Sdim SValBuilder &getSValBuilder() { return svalBuilder; } 133218887Sdim 134218887Sdim BugReporter& getBugReporter() { return BR; } 135218887Sdim 136234353Sdim const NodeBuilderContext &getBuilderContext() { 137243830Sdim assert(currBldrCtx); 138243830Sdim return *currBldrCtx; 139234353Sdim } 140218887Sdim 141226633Sdim bool isObjCGCEnabled() { return ObjCGCEnabled; } 142218887Sdim 143234353Sdim const Stmt *getStmt() const; 144234353Sdim 145234353Sdim void GenerateAutoTransition(ExplodedNode *N); 146234353Sdim void enqueueEndOfPath(ExplodedNodeSet &S); 147234353Sdim void GenerateCallExitNode(ExplodedNode *N); 148234353Sdim 149249423Sdim /// Visualize the ExplodedGraph created by executing the simulation. 150218887Sdim void ViewGraph(bool trim = false); 151218887Sdim 152249423Sdim /// Visualize a trimmed ExplodedGraph that only contains paths to the given 153249423Sdim /// nodes. 154249423Sdim void ViewGraph(ArrayRef<const ExplodedNode*> Nodes); 155218887Sdim 156218887Sdim /// getInitialState - Return the initial state used for the root vertex 157218887Sdim /// in the ExplodedGraph. 158234353Sdim ProgramStateRef getInitialState(const LocationContext *InitLoc); 159218887Sdim 160218887Sdim ExplodedGraph& getGraph() { return G; } 161218887Sdim const ExplodedGraph& getGraph() const { return G; } 162218887Sdim 163239462Sdim /// \brief Run the analyzer's garbage collection - remove dead symbols and 164249423Sdim /// bindings from the state. 165239462Sdim /// 166249423Sdim /// Checkers can participate in this process with two callbacks: 167249423Sdim /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation 168249423Sdim /// class for more information. 169249423Sdim /// 170249423Sdim /// \param Node The predecessor node, from which the processing should start. 171249423Sdim /// \param Out The returned set of output nodes. 172249423Sdim /// \param ReferenceStmt The statement which is about to be processed. 173249423Sdim /// Everything needed for this statement should be considered live. 174249423Sdim /// A null statement means that everything in child LocationContexts 175249423Sdim /// is dead. 176249423Sdim /// \param LC The location context of the \p ReferenceStmt. A null location 177249423Sdim /// context means that we have reached the end of analysis and that 178249423Sdim /// all statements and local variables should be considered dead. 179249423Sdim /// \param DiagnosticStmt Used as a location for any warnings that should 180249423Sdim /// occur while removing the dead (e.g. leaks). By default, the 181249423Sdim /// \p ReferenceStmt is used. 182249423Sdim /// \param K Denotes whether this is a pre- or post-statement purge. This 183249423Sdim /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an 184249423Sdim /// entire location context is being cleared, in which case the 185249423Sdim /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, 186249423Sdim /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) 187249423Sdim /// and \p ReferenceStmt must be valid (non-null). 188239462Sdim void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, 189249423Sdim const Stmt *ReferenceStmt, const LocationContext *LC, 190249423Sdim const Stmt *DiagnosticStmt = 0, 191239462Sdim ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); 192239462Sdim 193218887Sdim /// processCFGElement - Called by CoreEngine. Used to generate new successor 194218887Sdim /// nodes by processing the 'effects' of a CFG element. 195234353Sdim void processCFGElement(const CFGElement E, ExplodedNode *Pred, 196234353Sdim unsigned StmtIdx, NodeBuilderContext *Ctx); 197218887Sdim 198234353Sdim void ProcessStmt(const CFGStmt S, ExplodedNode *Pred); 199218887Sdim 200234353Sdim void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); 201218887Sdim 202234353Sdim void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred); 203218887Sdim 204218887Sdim void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 205234353Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 206263508Sdim void ProcessDeleteDtor(const CFGDeleteDtor D, 207263508Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 208234353Sdim void ProcessBaseDtor(const CFGBaseDtor D, 209234353Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 210234353Sdim void ProcessMemberDtor(const CFGMemberDtor D, 211234353Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 212218887Sdim void ProcessTemporaryDtor(const CFGTemporaryDtor D, 213234353Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 214218887Sdim 215218887Sdim /// Called by CoreEngine when processing the entrance of a CFGBlock. 216234353Sdim virtual void processCFGBlockEntrance(const BlockEdge &L, 217243830Sdim NodeBuilderWithSinks &nodeBuilder, 218243830Sdim ExplodedNode *Pred); 219218887Sdim 220218887Sdim /// ProcessBranch - Called by CoreEngine. Used to generate successor 221218887Sdim /// nodes by processing the 'effects' of a branch condition. 222226633Sdim void processBranch(const Stmt *Condition, const Stmt *Term, 223234353Sdim NodeBuilderContext& BuilderCtx, 224234353Sdim ExplodedNode *Pred, 225234353Sdim ExplodedNodeSet &Dst, 226234353Sdim const CFGBlock *DstT, 227234353Sdim const CFGBlock *DstF); 228218887Sdim 229249423Sdim /// Called by CoreEngine. Used to processing branching behavior 230249423Sdim /// at static initalizers. 231249423Sdim void processStaticInitializer(const DeclStmt *DS, 232249423Sdim NodeBuilderContext& BuilderCtx, 233249423Sdim ExplodedNode *Pred, 234249423Sdim ExplodedNodeSet &Dst, 235249423Sdim const CFGBlock *DstT, 236249423Sdim const CFGBlock *DstF); 237249423Sdim 238218887Sdim /// processIndirectGoto - Called by CoreEngine. Used to generate successor 239218887Sdim /// nodes by processing the 'effects' of a computed goto jump. 240218887Sdim void processIndirectGoto(IndirectGotoNodeBuilder& builder); 241218887Sdim 242218887Sdim /// ProcessSwitch - Called by CoreEngine. Used to generate successor 243218887Sdim /// nodes by processing the 'effects' of a switch statement. 244218887Sdim void processSwitch(SwitchNodeBuilder& builder); 245218887Sdim 246249423Sdim /// Called by CoreEngine. Used to generate end-of-path 247249423Sdim /// nodes when the control reaches the end of a function. 248243830Sdim void processEndOfFunction(NodeBuilderContext& BC, 249243830Sdim ExplodedNode *Pred); 250218887Sdim 251243830Sdim /// Remove dead bindings/symbols before exiting a function. 252243830Sdim void removeDeadOnEndOfFunction(NodeBuilderContext& BC, 253243830Sdim ExplodedNode *Pred, 254243830Sdim ExplodedNodeSet &Dst); 255243830Sdim 256218887Sdim /// Generate the entry node of the callee. 257234353Sdim void processCallEnter(CallEnter CE, ExplodedNode *Pred); 258218887Sdim 259239462Sdim /// Generate the sequence of nodes that simulate the call exit and the post 260239462Sdim /// visit for CallExpr. 261234353Sdim void processCallExit(ExplodedNode *Pred); 262218887Sdim 263218887Sdim /// Called by CoreEngine when the analysis worklist has terminated. 264218887Sdim void processEndWorklist(bool hasWorkRemaining); 265218887Sdim 266218887Sdim /// evalAssume - Callback function invoked by the ConstraintManager when 267218887Sdim /// making assumptions about state values. 268234353Sdim ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption); 269218887Sdim 270226633Sdim /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 271218887Sdim /// region change should trigger a processRegionChanges update. 272234353Sdim bool wantsRegionChangeUpdate(ProgramStateRef state); 273218887Sdim 274226633Sdim /// processRegionChanges - Called by ProgramStateManager whenever a change is made 275218887Sdim /// to the store. Used to update checkers that track region values. 276234353Sdim ProgramStateRef 277234353Sdim processRegionChanges(ProgramStateRef state, 278249423Sdim const InvalidatedSymbols *invalidated, 279226633Sdim ArrayRef<const MemRegion *> ExplicitRegions, 280234353Sdim ArrayRef<const MemRegion *> Regions, 281239462Sdim const CallEvent *Call); 282218887Sdim 283226633Sdim /// printState - Called by ProgramStateManager to print checker-specific data. 284234353Sdim void printState(raw_ostream &Out, ProgramStateRef State, 285226633Sdim const char *NL, const char *Sep); 286218887Sdim 287226633Sdim virtual ProgramStateManager& getStateManager() { return StateMgr; } 288226633Sdim 289218887Sdim StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 290218887Sdim 291218887Sdim ConstraintManager& getConstraintManager() { 292218887Sdim return StateMgr.getConstraintManager(); 293218887Sdim } 294218887Sdim 295218887Sdim // FIXME: Remove when we migrate over to just using SValBuilder. 296218887Sdim BasicValueFactory& getBasicVals() { 297218887Sdim return StateMgr.getBasicVals(); 298218887Sdim } 299218887Sdim 300218887Sdim // FIXME: Remove when we migrate over to just using ValueManager. 301218887Sdim SymbolManager& getSymbolManager() { return SymMgr; } 302218887Sdim const SymbolManager& getSymbolManager() const { return SymMgr; } 303218887Sdim 304218887Sdim // Functions for external checking of whether we have unfinished work 305221345Sdim bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } 306218887Sdim bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 307221345Sdim bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); } 308218887Sdim 309218887Sdim const CoreEngine &getCoreEngine() const { return Engine; } 310218887Sdim 311218887Sdimpublic: 312218887Sdim /// Visit - Transfer function logic for all statements. Dispatches to 313218887Sdim /// other functions that handle specific kinds of statements. 314226633Sdim void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); 315218887Sdim 316218887Sdim /// VisitArraySubscriptExpr - Transfer function for array accesses. 317226633Sdim void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, 318226633Sdim ExplodedNode *Pred, 319226633Sdim ExplodedNodeSet &Dst); 320218887Sdim 321243830Sdim /// VisitGCCAsmStmt - Transfer function logic for inline asm. 322243830Sdim void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 323243830Sdim ExplodedNodeSet &Dst); 324239462Sdim 325239462Sdim /// VisitMSAsmStmt - Transfer function logic for MS inline asm. 326239462Sdim void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 327239462Sdim ExplodedNodeSet &Dst); 328243830Sdim 329218887Sdim /// VisitBlockExpr - Transfer function logic for BlockExprs. 330218887Sdim void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 331218887Sdim ExplodedNodeSet &Dst); 332218887Sdim 333218887Sdim /// VisitBinaryOperator - Transfer function logic for binary operators. 334226633Sdim void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 335226633Sdim ExplodedNodeSet &Dst); 336218887Sdim 337218887Sdim 338218887Sdim /// VisitCall - Transfer function for function calls. 339226633Sdim void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, 340226633Sdim ExplodedNodeSet &Dst); 341218887Sdim 342218887Sdim /// VisitCast - Transfer function logic for all casts (implicit and explicit). 343218887Sdim void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, 344218887Sdim ExplodedNodeSet &Dst); 345218887Sdim 346218887Sdim /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. 347226633Sdim void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 348226633Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 349218887Sdim 350218887Sdim /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 351226633Sdim void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, 352226633Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 353218887Sdim 354218887Sdim /// VisitDeclStmt - Transfer function logic for DeclStmts. 355226633Sdim void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 356226633Sdim ExplodedNodeSet &Dst); 357218887Sdim 358218887Sdim /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 359226633Sdim void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 360226633Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 361218887Sdim 362226633Sdim void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, 363226633Sdim ExplodedNodeSet &Dst); 364218887Sdim 365218887Sdim /// VisitLogicalExpr - Transfer function logic for '&&', '||' 366226633Sdim void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 367226633Sdim ExplodedNodeSet &Dst); 368218887Sdim 369218887Sdim /// VisitMemberExpr - Transfer function for member expressions. 370226633Sdim void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 371226633Sdim ExplodedNodeSet &Dst); 372218887Sdim 373218887Sdim /// Transfer function logic for ObjCAtSynchronizedStmts. 374218887Sdim void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 375218887Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 376218887Sdim 377218887Sdim /// Transfer function logic for computing the lvalue of an Objective-C ivar. 378226633Sdim void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, 379226633Sdim ExplodedNodeSet &Dst); 380218887Sdim 381218887Sdim /// VisitObjCForCollectionStmt - Transfer function logic for 382218887Sdim /// ObjCForCollectionStmt. 383226633Sdim void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 384226633Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 385218887Sdim 386239462Sdim void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, 387226633Sdim ExplodedNodeSet &Dst); 388218887Sdim 389218887Sdim /// VisitReturnStmt - Transfer function logic for return statements. 390226633Sdim void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 391226633Sdim ExplodedNodeSet &Dst); 392218887Sdim 393218887Sdim /// VisitOffsetOfExpr - Transfer function for offsetof. 394226633Sdim void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, 395226633Sdim ExplodedNodeSet &Dst); 396218887Sdim 397221345Sdim /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. 398226633Sdim void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 399226633Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 400218887Sdim 401218887Sdim /// VisitUnaryOperator - Transfer function logic for unary operators. 402226633Sdim void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 403226633Sdim ExplodedNodeSet &Dst); 404218887Sdim 405234353Sdim /// Handle ++ and -- (both pre- and post-increment). 406234353Sdim void VisitIncrementDecrementOperator(const UnaryOperator* U, 407234353Sdim ExplodedNode *Pred, 408234353Sdim ExplodedNodeSet &Dst); 409234353Sdim 410234353Sdim void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 411234353Sdim ExplodedNodeSet &Dst); 412234353Sdim 413218887Sdim void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 414218887Sdim ExplodedNodeSet & Dst); 415218887Sdim 416239462Sdim void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, 417239462Sdim ExplodedNodeSet &Dst); 418218887Sdim 419243830Sdim void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, 420243830Sdim const Stmt *S, bool IsBaseDtor, 421218887Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst); 422218887Sdim 423218887Sdim void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 424218887Sdim ExplodedNodeSet &Dst); 425218887Sdim 426218887Sdim void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 427218887Sdim ExplodedNodeSet &Dst); 428218887Sdim 429218887Sdim /// Create a C++ temporary object for an rvalue. 430226633Sdim void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 431226633Sdim ExplodedNode *Pred, 432218887Sdim ExplodedNodeSet &Dst); 433221345Sdim 434243830Sdim /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic 435218887Sdim /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 436218887Sdim /// with those assumptions. 437243830Sdim void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 438218887Sdim const Expr *Ex); 439226633Sdim 440226633Sdim std::pair<const ProgramPointTag *, const ProgramPointTag*> 441243830Sdim geteagerlyAssumeBinOpBifurcationTags(); 442218887Sdim 443218887Sdim SVal evalMinus(SVal X) { 444249423Sdim return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X; 445218887Sdim } 446218887Sdim 447218887Sdim SVal evalComplement(SVal X) { 448249423Sdim return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X; 449218887Sdim } 450218887Sdim 451218887Sdimpublic: 452218887Sdim 453234353Sdim SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 454218887Sdim NonLoc L, NonLoc R, QualType T) { 455218887Sdim return svalBuilder.evalBinOpNN(state, op, L, R, T); 456218887Sdim } 457218887Sdim 458234353Sdim SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 459218887Sdim NonLoc L, SVal R, QualType T) { 460249423Sdim return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L, 461249423Sdim R.castAs<NonLoc>(), T) : R; 462218887Sdim } 463218887Sdim 464234353Sdim SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, 465218887Sdim SVal LHS, SVal RHS, QualType T) { 466218887Sdim return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 467218887Sdim } 468218887Sdim 469218887Sdimprotected: 470218887Sdim /// evalBind - Handle the semantics of binding a value to a specific location. 471218887Sdim /// This method is used by evalStore, VisitDeclStmt, and others. 472226633Sdim void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, 473243830Sdim SVal location, SVal Val, bool atDeclInit = false, 474243830Sdim const ProgramPoint *PP = 0); 475218887Sdim 476249423Sdim /// Call PointerEscape callback when a value escapes as a result of bind. 477249423Sdim ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, 478249423Sdim SVal Loc, SVal Val); 479249423Sdim /// Call PointerEscape callback when a value escapes as a result of 480249423Sdim /// region invalidation. 481263508Sdim /// \param[in] ITraits Specifies invalidation traits for regions/symbols. 482249423Sdim ProgramStateRef notifyCheckersOfPointerEscape( 483249423Sdim ProgramStateRef State, 484249423Sdim const InvalidatedSymbols *Invalidated, 485249423Sdim ArrayRef<const MemRegion *> ExplicitRegions, 486249423Sdim ArrayRef<const MemRegion *> Regions, 487249423Sdim const CallEvent *Call, 488263508Sdim RegionAndSymbolInvalidationTraits &ITraits); 489249423Sdim 490218887Sdimpublic: 491218887Sdim // FIXME: 'tag' should be removed, and a LocationContext should be used 492218887Sdim // instead. 493218887Sdim // FIXME: Comment on the meaning of the arguments, when 'St' may not 494218887Sdim // be the same as Pred->state, and when 'location' may not be the 495218887Sdim // same as state->getLValue(Ex). 496218887Sdim /// Simulate a read of the result of Ex. 497234353Sdim void evalLoad(ExplodedNodeSet &Dst, 498234353Sdim const Expr *NodeEx, /* Eventually will be a CFGStmt */ 499234353Sdim const Expr *BoundExpr, 500234353Sdim ExplodedNode *Pred, 501234353Sdim ProgramStateRef St, 502234353Sdim SVal location, 503234353Sdim const ProgramPointTag *tag = 0, 504218887Sdim QualType LoadTy = QualType()); 505218887Sdim 506218887Sdim // FIXME: 'tag' should be removed, and a LocationContext should be used 507218887Sdim // instead. 508226633Sdim void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, 509234353Sdim ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, 510226633Sdim const ProgramPointTag *tag = 0); 511239462Sdim 512239462Sdim /// \brief Create a new state in which the call return value is binded to the 513239462Sdim /// call origin expression. 514239462Sdim ProgramStateRef bindReturnValue(const CallEvent &Call, 515239462Sdim const LocationContext *LCtx, 516239462Sdim ProgramStateRef State); 517239462Sdim 518239462Sdim /// Evaluate a call, running pre- and post-call checks and allowing checkers 519239462Sdim /// to be responsible for handling the evaluation of the call itself. 520239462Sdim void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, 521239462Sdim const CallEvent &Call); 522239462Sdim 523239462Sdim /// \brief Default implementation of call evaluation. 524239462Sdim void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, 525239462Sdim const CallEvent &Call); 526218887Sdimprivate: 527234353Sdim void evalLoadCommon(ExplodedNodeSet &Dst, 528234353Sdim const Expr *NodeEx, /* Eventually will be a CFGStmt */ 529234353Sdim const Expr *BoundEx, 530234353Sdim ExplodedNode *Pred, 531234353Sdim ProgramStateRef St, 532234353Sdim SVal location, 533234353Sdim const ProgramPointTag *tag, 534218887Sdim QualType LoadTy); 535218887Sdim 536218887Sdim // FIXME: 'tag' should be removed, and a LocationContext should be used 537218887Sdim // instead. 538234353Sdim void evalLocation(ExplodedNodeSet &Dst, 539234353Sdim const Stmt *NodeEx, /* This will eventually be a CFGStmt */ 540234353Sdim const Stmt *BoundEx, 541234353Sdim ExplodedNode *Pred, 542234353Sdim ProgramStateRef St, SVal location, 543226633Sdim const ProgramPointTag *tag, bool isLoad); 544218887Sdim 545243830Sdim /// Count the stack depth and determine if the call is recursive. 546243830Sdim void examineStackFrames(const Decl *D, const LocationContext *LCtx, 547243830Sdim bool &IsRecursive, unsigned &StackDepth); 548243830Sdim 549249423Sdim /// Checks our policies and decides weither the given call should be inlined. 550249423Sdim bool shouldInlineCall(const CallEvent &Call, const Decl *D, 551249423Sdim const ExplodedNode *Pred); 552249423Sdim 553239462Sdim bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 554239462Sdim ExplodedNode *Pred, ProgramStateRef State); 555234353Sdim 556239462Sdim /// \brief Conservatively evaluate call by invalidating regions and binding 557239462Sdim /// a conjured return value. 558239462Sdim void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, 559239462Sdim ExplodedNode *Pred, ProgramStateRef State); 560239462Sdim 561239462Sdim /// \brief Either inline or process the call conservatively (or both), based 562239462Sdim /// on DynamicDispatchBifurcation data. 563239462Sdim void BifurcateCall(const MemRegion *BifurReg, 564239462Sdim const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 565239462Sdim ExplodedNode *Pred); 566239462Sdim 567234353Sdim bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); 568249423Sdim 569249423Sdim /// Models a trivial copy or move constructor or trivial assignment operator 570249423Sdim /// call with a simple bind. 571249423Sdim void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 572249423Sdim const CallEvent &Call); 573249423Sdim 574249423Sdim /// If the value of the given expression is a NonLoc, copy it into a new 575249423Sdim /// temporary object region, and replace the value of the expression with 576249423Sdim /// that. 577249423Sdim /// 578249423Sdim /// If \p ResultE is provided, the new region will be bound to this expression 579249423Sdim /// instead of \p E. 580249423Sdim ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, 581249423Sdim const LocationContext *LC, 582249423Sdim const Expr *E, 583249423Sdim const Expr *ResultE = 0); 584218887Sdim}; 585218887Sdim 586234353Sdim/// Traits for storing the call processing policy inside GDM. 587234353Sdim/// The GDM stores the corresponding CallExpr pointer. 588243830Sdim// FIXME: This does not use the nice trait macros because it must be accessible 589243830Sdim// from multiple translation units. 590234353Sdimstruct ReplayWithoutInlining{}; 591234353Sdimtemplate <> 592234353Sdimstruct ProgramStateTrait<ReplayWithoutInlining> : 593249423Sdim public ProgramStatePartialTrait<const void*> { 594234353Sdim static void *GDMIndex() { static int index = 0; return &index; } 595234353Sdim}; 596234353Sdim 597218887Sdim} // end ento namespace 598218887Sdim 599218887Sdim} // end clang namespace 600218887Sdim 601218887Sdim#endif 602