1//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines a meta-engine for path-sensitive dataflow analysis that 11// is built on CoreEngine, but provides the boilerplate to execute transfer 12// functions and build the ExplodedGraph at the expression level. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CLANG_GR_EXPRENGINE 17#define LLVM_CLANG_GR_EXPRENGINE 18 19#include "clang/AST/Expr.h" 20#include "clang/AST/Type.h" 21#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" 22#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 23#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 24#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 25#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 26#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 27#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 28 29namespace clang { 30 31class AnalysisDeclContextManager; 32class CXXCatchStmt; 33class CXXConstructExpr; 34class CXXDeleteExpr; 35class CXXNewExpr; 36class CXXTemporaryObjectExpr; 37class CXXThisExpr; 38class MaterializeTemporaryExpr; 39class ObjCAtSynchronizedStmt; 40class ObjCForCollectionStmt; 41 42namespace ento { 43 44class AnalysisManager; 45class CallEvent; 46class SimpleCall; 47class CXXConstructorCall; 48 49class ExprEngine : public SubEngine { 50public: 51 /// The modes of inlining, which override the default analysis-wide settings. 52 enum InliningModes { 53 /// Follow the default settings for inlining callees. 54 Inline_Regular = 0, 55 /// Do minimal inlining of callees. 56 Inline_Minimal = 0x1 57 }; 58 59private: 60 AnalysisManager &AMgr; 61 62 AnalysisDeclContextManager &AnalysisDeclContexts; 63 64 CoreEngine Engine; 65 66 /// G - the simulation graph. 67 ExplodedGraph& G; 68 69 /// StateMgr - Object that manages the data for all created states. 70 ProgramStateManager StateMgr; 71 72 /// SymMgr - Object that manages the symbol information. 73 SymbolManager& SymMgr; 74 75 /// svalBuilder - SValBuilder object that creates SVals from expressions. 76 SValBuilder &svalBuilder; 77 78 unsigned int currStmtIdx; 79 const NodeBuilderContext *currBldrCtx; 80 81 /// Helper object to determine if an Objective-C message expression 82 /// implicitly never returns. 83 ObjCNoReturn ObjCNoRet; 84 85 /// Whether or not GC is enabled in this analysis. 86 bool ObjCGCEnabled; 87 88 /// The BugReporter associated with this engine. It is important that 89 /// this object be placed at the very end of member variables so that its 90 /// destructor is called before the rest of the ExprEngine is destroyed. 91 GRBugReporter BR; 92 93 /// The functions which have been analyzed through inlining. This is owned by 94 /// AnalysisConsumer. It can be null. 95 SetOfConstDecls *VisitedCallees; 96 97 /// The flag, which specifies the mode of inlining for the engine. 98 InliningModes HowToInline; 99 100public: 101 ExprEngine(AnalysisManager &mgr, bool gcEnabled, 102 SetOfConstDecls *VisitedCalleesIn, 103 FunctionSummariesTy *FS, 104 InliningModes HowToInlineIn); 105 106 ~ExprEngine(); 107 108 /// Returns true if there is still simulation state on the worklist. 109 bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 110 return Engine.ExecuteWorkList(L, Steps, 0); 111 } 112 113 /// Execute the work list with an initial state. Nodes that reaches the exit 114 /// of the function are added into the Dst set, which represent the exit 115 /// state of the function call. Returns true if there is still simulation 116 /// state on the worklist. 117 bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 118 ProgramStateRef InitState, 119 ExplodedNodeSet &Dst) { 120 return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 121 } 122 123 /// getContext - Return the ASTContext associated with this analysis. 124 ASTContext &getContext() const { return AMgr.getASTContext(); } 125 126 virtual AnalysisManager &getAnalysisManager() { return AMgr; } 127 128 CheckerManager &getCheckerManager() const { 129 return *AMgr.getCheckerManager(); 130 } 131 132 SValBuilder &getSValBuilder() { return svalBuilder; } 133 134 BugReporter& getBugReporter() { return BR; } 135 136 const NodeBuilderContext &getBuilderContext() { 137 assert(currBldrCtx); 138 return *currBldrCtx; 139 } 140 141 bool isObjCGCEnabled() { return ObjCGCEnabled; } 142 143 const Stmt *getStmt() const; 144 145 void GenerateAutoTransition(ExplodedNode *N); 146 void enqueueEndOfPath(ExplodedNodeSet &S); 147 void GenerateCallExitNode(ExplodedNode *N); 148 149 /// Visualize the ExplodedGraph created by executing the simulation. 150 void ViewGraph(bool trim = false); 151 152 /// Visualize a trimmed ExplodedGraph that only contains paths to the given 153 /// nodes. 154 void ViewGraph(ArrayRef<const ExplodedNode*> Nodes); 155 156 /// getInitialState - Return the initial state used for the root vertex 157 /// in the ExplodedGraph. 158 ProgramStateRef getInitialState(const LocationContext *InitLoc); 159 160 ExplodedGraph& getGraph() { return G; } 161 const ExplodedGraph& getGraph() const { return G; } 162 163 /// \brief Run the analyzer's garbage collection - remove dead symbols and 164 /// bindings from the state. 165 /// 166 /// Checkers can participate in this process with two callbacks: 167 /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation 168 /// class for more information. 169 /// 170 /// \param Node The predecessor node, from which the processing should start. 171 /// \param Out The returned set of output nodes. 172 /// \param ReferenceStmt The statement which is about to be processed. 173 /// Everything needed for this statement should be considered live. 174 /// A null statement means that everything in child LocationContexts 175 /// is dead. 176 /// \param LC The location context of the \p ReferenceStmt. A null location 177 /// context means that we have reached the end of analysis and that 178 /// all statements and local variables should be considered dead. 179 /// \param DiagnosticStmt Used as a location for any warnings that should 180 /// occur while removing the dead (e.g. leaks). By default, the 181 /// \p ReferenceStmt is used. 182 /// \param K Denotes whether this is a pre- or post-statement purge. This 183 /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an 184 /// entire location context is being cleared, in which case the 185 /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, 186 /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) 187 /// and \p ReferenceStmt must be valid (non-null). 188 void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, 189 const Stmt *ReferenceStmt, const LocationContext *LC, 190 const Stmt *DiagnosticStmt = 0, 191 ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); 192 193 /// processCFGElement - Called by CoreEngine. Used to generate new successor 194 /// nodes by processing the 'effects' of a CFG element. 195 void processCFGElement(const CFGElement E, ExplodedNode *Pred, 196 unsigned StmtIdx, NodeBuilderContext *Ctx); 197 198 void ProcessStmt(const CFGStmt S, ExplodedNode *Pred); 199 200 void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); 201 202 void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred); 203 204 void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 205 ExplodedNode *Pred, ExplodedNodeSet &Dst); 206 void ProcessDeleteDtor(const CFGDeleteDtor D, 207 ExplodedNode *Pred, ExplodedNodeSet &Dst); 208 void ProcessBaseDtor(const CFGBaseDtor D, 209 ExplodedNode *Pred, ExplodedNodeSet &Dst); 210 void ProcessMemberDtor(const CFGMemberDtor D, 211 ExplodedNode *Pred, ExplodedNodeSet &Dst); 212 void ProcessTemporaryDtor(const CFGTemporaryDtor D, 213 ExplodedNode *Pred, ExplodedNodeSet &Dst); 214 215 /// Called by CoreEngine when processing the entrance of a CFGBlock. 216 virtual void processCFGBlockEntrance(const BlockEdge &L, 217 NodeBuilderWithSinks &nodeBuilder, 218 ExplodedNode *Pred); 219 220 /// ProcessBranch - Called by CoreEngine. Used to generate successor 221 /// nodes by processing the 'effects' of a branch condition. 222 void processBranch(const Stmt *Condition, const Stmt *Term, 223 NodeBuilderContext& BuilderCtx, 224 ExplodedNode *Pred, 225 ExplodedNodeSet &Dst, 226 const CFGBlock *DstT, 227 const CFGBlock *DstF); 228 229 /// Called by CoreEngine. Used to processing branching behavior 230 /// at static initalizers. 231 void processStaticInitializer(const DeclStmt *DS, 232 NodeBuilderContext& BuilderCtx, 233 ExplodedNode *Pred, 234 ExplodedNodeSet &Dst, 235 const CFGBlock *DstT, 236 const CFGBlock *DstF); 237 238 /// processIndirectGoto - Called by CoreEngine. Used to generate successor 239 /// nodes by processing the 'effects' of a computed goto jump. 240 void processIndirectGoto(IndirectGotoNodeBuilder& builder); 241 242 /// ProcessSwitch - Called by CoreEngine. Used to generate successor 243 /// nodes by processing the 'effects' of a switch statement. 244 void processSwitch(SwitchNodeBuilder& builder); 245 246 /// Called by CoreEngine. Used to generate end-of-path 247 /// nodes when the control reaches the end of a function. 248 void processEndOfFunction(NodeBuilderContext& BC, 249 ExplodedNode *Pred); 250 251 /// Remove dead bindings/symbols before exiting a function. 252 void removeDeadOnEndOfFunction(NodeBuilderContext& BC, 253 ExplodedNode *Pred, 254 ExplodedNodeSet &Dst); 255 256 /// Generate the entry node of the callee. 257 void processCallEnter(CallEnter CE, ExplodedNode *Pred); 258 259 /// Generate the sequence of nodes that simulate the call exit and the post 260 /// visit for CallExpr. 261 void processCallExit(ExplodedNode *Pred); 262 263 /// Called by CoreEngine when the analysis worklist has terminated. 264 void processEndWorklist(bool hasWorkRemaining); 265 266 /// evalAssume - Callback function invoked by the ConstraintManager when 267 /// making assumptions about state values. 268 ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption); 269 270 /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 271 /// region change should trigger a processRegionChanges update. 272 bool wantsRegionChangeUpdate(ProgramStateRef state); 273 274 /// processRegionChanges - Called by ProgramStateManager whenever a change is made 275 /// to the store. Used to update checkers that track region values. 276 ProgramStateRef 277 processRegionChanges(ProgramStateRef state, 278 const InvalidatedSymbols *invalidated, 279 ArrayRef<const MemRegion *> ExplicitRegions, 280 ArrayRef<const MemRegion *> Regions, 281 const CallEvent *Call); 282 283 /// printState - Called by ProgramStateManager to print checker-specific data. 284 void printState(raw_ostream &Out, ProgramStateRef State, 285 const char *NL, const char *Sep); 286 287 virtual ProgramStateManager& getStateManager() { return StateMgr; } 288 289 StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 290 291 ConstraintManager& getConstraintManager() { 292 return StateMgr.getConstraintManager(); 293 } 294 295 // FIXME: Remove when we migrate over to just using SValBuilder. 296 BasicValueFactory& getBasicVals() { 297 return StateMgr.getBasicVals(); 298 } 299 300 // FIXME: Remove when we migrate over to just using ValueManager. 301 SymbolManager& getSymbolManager() { return SymMgr; } 302 const SymbolManager& getSymbolManager() const { return SymMgr; } 303 304 // Functions for external checking of whether we have unfinished work 305 bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } 306 bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 307 bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); } 308 309 const CoreEngine &getCoreEngine() const { return Engine; } 310 311public: 312 /// Visit - Transfer function logic for all statements. Dispatches to 313 /// other functions that handle specific kinds of statements. 314 void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); 315 316 /// VisitArraySubscriptExpr - Transfer function for array accesses. 317 void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, 318 ExplodedNode *Pred, 319 ExplodedNodeSet &Dst); 320 321 /// VisitGCCAsmStmt - Transfer function logic for inline asm. 322 void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 323 ExplodedNodeSet &Dst); 324 325 /// VisitMSAsmStmt - Transfer function logic for MS inline asm. 326 void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 327 ExplodedNodeSet &Dst); 328 329 /// VisitBlockExpr - Transfer function logic for BlockExprs. 330 void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 331 ExplodedNodeSet &Dst); 332 333 /// VisitBinaryOperator - Transfer function logic for binary operators. 334 void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 335 ExplodedNodeSet &Dst); 336 337 338 /// VisitCall - Transfer function for function calls. 339 void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, 340 ExplodedNodeSet &Dst); 341 342 /// VisitCast - Transfer function logic for all casts (implicit and explicit). 343 void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, 344 ExplodedNodeSet &Dst); 345 346 /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. 347 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 348 ExplodedNode *Pred, ExplodedNodeSet &Dst); 349 350 /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 351 void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, 352 ExplodedNode *Pred, ExplodedNodeSet &Dst); 353 354 /// VisitDeclStmt - Transfer function logic for DeclStmts. 355 void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 356 ExplodedNodeSet &Dst); 357 358 /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 359 void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 360 ExplodedNode *Pred, ExplodedNodeSet &Dst); 361 362 void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, 363 ExplodedNodeSet &Dst); 364 365 /// VisitLogicalExpr - Transfer function logic for '&&', '||' 366 void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 367 ExplodedNodeSet &Dst); 368 369 /// VisitMemberExpr - Transfer function for member expressions. 370 void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 371 ExplodedNodeSet &Dst); 372 373 /// Transfer function logic for ObjCAtSynchronizedStmts. 374 void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 375 ExplodedNode *Pred, ExplodedNodeSet &Dst); 376 377 /// Transfer function logic for computing the lvalue of an Objective-C ivar. 378 void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, 379 ExplodedNodeSet &Dst); 380 381 /// VisitObjCForCollectionStmt - Transfer function logic for 382 /// ObjCForCollectionStmt. 383 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 384 ExplodedNode *Pred, ExplodedNodeSet &Dst); 385 386 void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, 387 ExplodedNodeSet &Dst); 388 389 /// VisitReturnStmt - Transfer function logic for return statements. 390 void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 391 ExplodedNodeSet &Dst); 392 393 /// VisitOffsetOfExpr - Transfer function for offsetof. 394 void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, 395 ExplodedNodeSet &Dst); 396 397 /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. 398 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 399 ExplodedNode *Pred, ExplodedNodeSet &Dst); 400 401 /// VisitUnaryOperator - Transfer function logic for unary operators. 402 void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 403 ExplodedNodeSet &Dst); 404 405 /// Handle ++ and -- (both pre- and post-increment). 406 void VisitIncrementDecrementOperator(const UnaryOperator* U, 407 ExplodedNode *Pred, 408 ExplodedNodeSet &Dst); 409 410 void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 411 ExplodedNodeSet &Dst); 412 413 void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 414 ExplodedNodeSet & Dst); 415 416 void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, 417 ExplodedNodeSet &Dst); 418 419 void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, 420 const Stmt *S, bool IsBaseDtor, 421 ExplodedNode *Pred, ExplodedNodeSet &Dst); 422 423 void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 424 ExplodedNodeSet &Dst); 425 426 void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 427 ExplodedNodeSet &Dst); 428 429 /// Create a C++ temporary object for an rvalue. 430 void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 431 ExplodedNode *Pred, 432 ExplodedNodeSet &Dst); 433 434 /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic 435 /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 436 /// with those assumptions. 437 void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 438 const Expr *Ex); 439 440 std::pair<const ProgramPointTag *, const ProgramPointTag*> 441 geteagerlyAssumeBinOpBifurcationTags(); 442 443 SVal evalMinus(SVal X) { 444 return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X; 445 } 446 447 SVal evalComplement(SVal X) { 448 return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X; 449 } 450 451public: 452 453 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 454 NonLoc L, NonLoc R, QualType T) { 455 return svalBuilder.evalBinOpNN(state, op, L, R, T); 456 } 457 458 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 459 NonLoc L, SVal R, QualType T) { 460 return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L, 461 R.castAs<NonLoc>(), T) : R; 462 } 463 464 SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, 465 SVal LHS, SVal RHS, QualType T) { 466 return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 467 } 468 469protected: 470 /// evalBind - Handle the semantics of binding a value to a specific location. 471 /// This method is used by evalStore, VisitDeclStmt, and others. 472 void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, 473 SVal location, SVal Val, bool atDeclInit = false, 474 const ProgramPoint *PP = 0); 475 476 /// Call PointerEscape callback when a value escapes as a result of bind. 477 ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, 478 SVal Loc, SVal Val); 479 /// Call PointerEscape callback when a value escapes as a result of 480 /// region invalidation. 481 /// \param[in] ITraits Specifies invalidation traits for regions/symbols. 482 ProgramStateRef notifyCheckersOfPointerEscape( 483 ProgramStateRef State, 484 const InvalidatedSymbols *Invalidated, 485 ArrayRef<const MemRegion *> ExplicitRegions, 486 ArrayRef<const MemRegion *> Regions, 487 const CallEvent *Call, 488 RegionAndSymbolInvalidationTraits &ITraits); 489 490public: 491 // FIXME: 'tag' should be removed, and a LocationContext should be used 492 // instead. 493 // FIXME: Comment on the meaning of the arguments, when 'St' may not 494 // be the same as Pred->state, and when 'location' may not be the 495 // same as state->getLValue(Ex). 496 /// Simulate a read of the result of Ex. 497 void evalLoad(ExplodedNodeSet &Dst, 498 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 499 const Expr *BoundExpr, 500 ExplodedNode *Pred, 501 ProgramStateRef St, 502 SVal location, 503 const ProgramPointTag *tag = 0, 504 QualType LoadTy = QualType()); 505 506 // FIXME: 'tag' should be removed, and a LocationContext should be used 507 // instead. 508 void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, 509 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, 510 const ProgramPointTag *tag = 0); 511 512 /// \brief Create a new state in which the call return value is binded to the 513 /// call origin expression. 514 ProgramStateRef bindReturnValue(const CallEvent &Call, 515 const LocationContext *LCtx, 516 ProgramStateRef State); 517 518 /// Evaluate a call, running pre- and post-call checks and allowing checkers 519 /// to be responsible for handling the evaluation of the call itself. 520 void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, 521 const CallEvent &Call); 522 523 /// \brief Default implementation of call evaluation. 524 void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, 525 const CallEvent &Call); 526private: 527 void evalLoadCommon(ExplodedNodeSet &Dst, 528 const Expr *NodeEx, /* Eventually will be a CFGStmt */ 529 const Expr *BoundEx, 530 ExplodedNode *Pred, 531 ProgramStateRef St, 532 SVal location, 533 const ProgramPointTag *tag, 534 QualType LoadTy); 535 536 // FIXME: 'tag' should be removed, and a LocationContext should be used 537 // instead. 538 void evalLocation(ExplodedNodeSet &Dst, 539 const Stmt *NodeEx, /* This will eventually be a CFGStmt */ 540 const Stmt *BoundEx, 541 ExplodedNode *Pred, 542 ProgramStateRef St, SVal location, 543 const ProgramPointTag *tag, bool isLoad); 544 545 /// Count the stack depth and determine if the call is recursive. 546 void examineStackFrames(const Decl *D, const LocationContext *LCtx, 547 bool &IsRecursive, unsigned &StackDepth); 548 549 /// Checks our policies and decides weither the given call should be inlined. 550 bool shouldInlineCall(const CallEvent &Call, const Decl *D, 551 const ExplodedNode *Pred); 552 553 bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 554 ExplodedNode *Pred, ProgramStateRef State); 555 556 /// \brief Conservatively evaluate call by invalidating regions and binding 557 /// a conjured return value. 558 void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, 559 ExplodedNode *Pred, ProgramStateRef State); 560 561 /// \brief Either inline or process the call conservatively (or both), based 562 /// on DynamicDispatchBifurcation data. 563 void BifurcateCall(const MemRegion *BifurReg, 564 const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 565 ExplodedNode *Pred); 566 567 bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); 568 569 /// Models a trivial copy or move constructor or trivial assignment operator 570 /// call with a simple bind. 571 void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 572 const CallEvent &Call); 573 574 /// If the value of the given expression is a NonLoc, copy it into a new 575 /// temporary object region, and replace the value of the expression with 576 /// that. 577 /// 578 /// If \p ResultE is provided, the new region will be bound to this expression 579 /// instead of \p E. 580 ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, 581 const LocationContext *LC, 582 const Expr *E, 583 const Expr *ResultE = 0); 584}; 585 586/// Traits for storing the call processing policy inside GDM. 587/// The GDM stores the corresponding CallExpr pointer. 588// FIXME: This does not use the nice trait macros because it must be accessible 589// from multiple translation units. 590struct ReplayWithoutInlining{}; 591template <> 592struct ProgramStateTrait<ReplayWithoutInlining> : 593 public ProgramStatePartialTrait<const void*> { 594 static void *GDMIndex() { static int index = 0; return &index; } 595}; 596 597} // end ento namespace 598 599} // end clang namespace 600 601#endif 602