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 
29 namespace clang {
30 
31 class AnalysisDeclContextManager;
32 class CXXCatchStmt;
33 class CXXConstructExpr;
34 class CXXDeleteExpr;
35 class CXXNewExpr;
36 class CXXTemporaryObjectExpr;
37 class CXXThisExpr;
38 class MaterializeTemporaryExpr;
39 class ObjCAtSynchronizedStmt;
40 class ObjCForCollectionStmt;
41 
42 namespace ento {
43 
44 class AnalysisManager;
45 class CallEvent;
46 class SimpleCall;
47 class CXXConstructorCall;
48 
49 class ExprEngine : public SubEngine {
50 public:
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 
59 private:
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 
100 public:
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.
ExecuteWorkListWithInitialState(const LocationContext * L,unsigned Steps,ProgramStateRef InitState,ExplodedNodeSet & Dst)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.
getContext()124   ASTContext &getContext() const { return AMgr.getASTContext(); }
125 
getAnalysisManager()126   virtual AnalysisManager &getAnalysisManager() { return AMgr; }
127 
getCheckerManager()128   CheckerManager &getCheckerManager() const {
129     return *AMgr.getCheckerManager();
130   }
131 
getSValBuilder()132   SValBuilder &getSValBuilder() { return svalBuilder; }
133 
getBugReporter()134   BugReporter& getBugReporter() { return BR; }
135 
getBuilderContext()136   const NodeBuilderContext &getBuilderContext() {
137     assert(currBldrCtx);
138     return *currBldrCtx;
139   }
140 
isObjCGCEnabled()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 
getGraph()160   ExplodedGraph& getGraph() { return G; }
getGraph()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 
getStateManager()287   virtual ProgramStateManager& getStateManager() { return StateMgr; }
288 
getStoreManager()289   StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
290 
getConstraintManager()291   ConstraintManager& getConstraintManager() {
292     return StateMgr.getConstraintManager();
293   }
294 
295   // FIXME: Remove when we migrate over to just using SValBuilder.
getBasicVals()296   BasicValueFactory& getBasicVals() {
297     return StateMgr.getBasicVals();
298   }
299 
300   // FIXME: Remove when we migrate over to just using ValueManager.
getSymbolManager()301   SymbolManager& getSymbolManager() { return SymMgr; }
getSymbolManager()302   const SymbolManager& getSymbolManager() const { return SymMgr; }
303 
304   // Functions for external checking of whether we have unfinished work
wasBlocksExhausted()305   bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
hasEmptyWorkList()306   bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
hasWorkRemaining()307   bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
308 
getCoreEngine()309   const CoreEngine &getCoreEngine() const { return Engine; }
310 
311 public:
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 
evalMinus(SVal X)443   SVal evalMinus(SVal X) {
444     return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
445   }
446 
evalComplement(SVal X)447   SVal evalComplement(SVal X) {
448     return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
449   }
450 
451 public:
452 
evalBinOp(ProgramStateRef state,BinaryOperator::Opcode op,NonLoc L,NonLoc R,QualType T)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 
evalBinOp(ProgramStateRef state,BinaryOperator::Opcode op,NonLoc L,SVal R,QualType T)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 
evalBinOp(ProgramStateRef ST,BinaryOperator::Opcode Op,SVal LHS,SVal RHS,QualType T)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 
469 protected:
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 
490 public:
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);
526 private:
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.
590 struct ReplayWithoutInlining{};
591 template <>
592 struct 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