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