Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines a meta-engine for path-sensitive dataflow analysis that
10
//  is built on CoreEngine, but provides the boilerplate to execute transfer
11
//  functions and build the ExplodedGraph at the expression level.
12
//
13
//===----------------------------------------------------------------------===//
14
 
15
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
16
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
17
 
18
#include "clang/AST/Expr.h"
19
#include "clang/AST/Type.h"
20
#include "clang/Analysis/CFG.h"
21
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
22
#include "clang/Analysis/ProgramPoint.h"
23
#include "clang/Basic/LLVM.h"
24
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
25
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
26
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
27
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
28
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
29
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
30
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
31
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
32
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
33
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
34
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
35
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
36
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
37
#include "llvm/ADT/ArrayRef.h"
38
#include <cassert>
39
#include <optional>
40
#include <utility>
41
 
42
namespace clang {
43
 
44
class AnalysisDeclContextManager;
45
class AnalyzerOptions;
46
class ASTContext;
47
class CFGBlock;
48
class CFGElement;
49
class ConstructionContext;
50
class CXXBindTemporaryExpr;
51
class CXXCatchStmt;
52
class CXXConstructExpr;
53
class CXXDeleteExpr;
54
class CXXNewExpr;
55
class CXXThisExpr;
56
class Decl;
57
class DeclStmt;
58
class GCCAsmStmt;
59
class LambdaExpr;
60
class LocationContext;
61
class MaterializeTemporaryExpr;
62
class MSAsmStmt;
63
class NamedDecl;
64
class ObjCAtSynchronizedStmt;
65
class ObjCForCollectionStmt;
66
class ObjCIvarRefExpr;
67
class ObjCMessageExpr;
68
class ReturnStmt;
69
class Stmt;
70
 
71
namespace cross_tu {
72
 
73
class CrossTranslationUnitContext;
74
 
75
} // namespace cross_tu
76
 
77
namespace ento {
78
 
79
class AnalysisManager;
80
class BasicValueFactory;
81
class CallEvent;
82
class CheckerManager;
83
class ConstraintManager;
84
class ExplodedNodeSet;
85
class ExplodedNode;
86
class IndirectGotoNodeBuilder;
87
class MemRegion;
88
struct NodeBuilderContext;
89
class NodeBuilderWithSinks;
90
class ProgramState;
91
class ProgramStateManager;
92
class RegionAndSymbolInvalidationTraits;
93
class SymbolManager;
94
class SwitchNodeBuilder;
95
 
96
/// Hints for figuring out of a call should be inlined during evalCall().
97
struct EvalCallOptions {
98
  /// This call is a constructor or a destructor for which we do not currently
99
  /// compute the this-region correctly.
100
  bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false;
101
 
102
  /// This call is a constructor or a destructor for a single element within
103
  /// an array, a part of array construction or destruction.
104
  bool IsArrayCtorOrDtor = false;
105
 
106
  /// This call is a constructor or a destructor of a temporary value.
107
  bool IsTemporaryCtorOrDtor = false;
108
 
109
  /// This call is a constructor for a temporary that is lifetime-extended
110
  /// by binding it to a reference-type field within an aggregate,
111
  /// for example 'A { const C &c; }; A a = { C() };'
112
  bool IsTemporaryLifetimeExtendedViaAggregate = false;
113
 
114
  /// This call is a pre-C++17 elidable constructor that we failed to elide
115
  /// because we failed to compute the target region into which
116
  /// this constructor would have been ultimately elided. Analysis that
117
  /// we perform in this case is still correct but it behaves differently,
118
  /// as if copy elision is disabled.
119
  bool IsElidableCtorThatHasNotBeenElided = false;
120
 
121
  EvalCallOptions() {}
122
};
123
 
124
class ExprEngine {
125
  void anchor();
126
 
127
public:
128
  /// The modes of inlining, which override the default analysis-wide settings.
129
  enum InliningModes {
130
    /// Follow the default settings for inlining callees.
131
    Inline_Regular = 0,
132
 
133
    /// Do minimal inlining of callees.
134
    Inline_Minimal = 0x1
135
  };
136
 
137
private:
138
  cross_tu::CrossTranslationUnitContext &CTU;
139
  bool IsCTUEnabled;
140
 
141
  AnalysisManager &AMgr;
142
 
143
  AnalysisDeclContextManager &AnalysisDeclContexts;
144
 
145
  CoreEngine Engine;
146
 
147
  /// G - the simulation graph.
148
  ExplodedGraph &G;
149
 
150
  /// StateMgr - Object that manages the data for all created states.
151
  ProgramStateManager StateMgr;
152
 
153
  /// SymMgr - Object that manages the symbol information.
154
  SymbolManager &SymMgr;
155
 
156
  /// MRMgr - MemRegionManager object that creates memory regions.
157
  MemRegionManager &MRMgr;
158
 
159
  /// svalBuilder - SValBuilder object that creates SVals from expressions.
160
  SValBuilder &svalBuilder;
161
 
162
  unsigned int currStmtIdx = 0;
163
  const NodeBuilderContext *currBldrCtx = nullptr;
164
 
165
  /// Helper object to determine if an Objective-C message expression
166
  /// implicitly never returns.
167
  ObjCNoReturn ObjCNoRet;
168
 
169
  /// The BugReporter associated with this engine.  It is important that
170
  /// this object be placed at the very end of member variables so that its
171
  /// destructor is called before the rest of the ExprEngine is destroyed.
172
  PathSensitiveBugReporter BR;
173
 
174
  /// The functions which have been analyzed through inlining. This is owned by
175
  /// AnalysisConsumer. It can be null.
176
  SetOfConstDecls *VisitedCallees;
177
 
178
  /// The flag, which specifies the mode of inlining for the engine.
179
  InliningModes HowToInline;
180
 
181
public:
182
  ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
183
             SetOfConstDecls *VisitedCalleesIn,
184
             FunctionSummariesTy *FS, InliningModes HowToInlineIn);
185
 
186
  virtual ~ExprEngine() = default;
187
 
188
  /// Returns true if there is still simulation state on the worklist.
189
  bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
190
    return Engine.ExecuteWorkList(L, Steps, nullptr);
191
  }
192
 
193
  /// Execute the work list with an initial state. Nodes that reaches the exit
194
  /// of the function are added into the Dst set, which represent the exit
195
  /// state of the function call. Returns true if there is still simulation
196
  /// state on the worklist.
197
  bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
198
                                       ProgramStateRef InitState,
199
                                       ExplodedNodeSet &Dst) {
200
    return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
201
  }
202
 
203
  /// getContext - Return the ASTContext associated with this analysis.
204
  ASTContext &getContext() const { return AMgr.getASTContext(); }
205
 
206
  AnalysisManager &getAnalysisManager() { return AMgr; }
207
 
208
  AnalysisDeclContextManager &getAnalysisDeclContextManager() {
209
    return AMgr.getAnalysisDeclContextManager();
210
  }
211
 
212
  CheckerManager &getCheckerManager() const {
213
    return *AMgr.getCheckerManager();
214
  }
215
 
216
  SValBuilder &getSValBuilder() { return svalBuilder; }
217
 
218
  BugReporter &getBugReporter() { return BR; }
219
 
220
  cross_tu::CrossTranslationUnitContext *
221
  getCrossTranslationUnitContext() {
222
    return &CTU;
223
  }
224
 
225
  const NodeBuilderContext &getBuilderContext() {
226
    assert(currBldrCtx);
227
    return *currBldrCtx;
228
  }
229
 
230
  const Stmt *getStmt() const;
231
 
232
  const LocationContext *getRootLocationContext() const {
233
    assert(G.roots_begin() != G.roots_end());
234
    return (*G.roots_begin())->getLocation().getLocationContext();
235
  }
236
 
237
  void GenerateAutoTransition(ExplodedNode *N);
238
  void enqueueEndOfPath(ExplodedNodeSet &S);
239
  void GenerateCallExitNode(ExplodedNode *N);
240
 
241
 
242
  /// Dump graph to the specified filename.
243
  /// If filename is empty, generate a temporary one.
244
  /// \return The filename the graph is written into.
245
  std::string DumpGraph(bool trim = false, StringRef Filename="");
246
 
247
  /// Dump the graph consisting of the given nodes to a specified filename.
248
  /// Generate a temporary filename if it's not provided.
249
  /// \return The filename the graph is written into.
250
  std::string DumpGraph(ArrayRef<const ExplodedNode *> Nodes,
251
                        StringRef Filename = "");
252
 
253
  /// Visualize the ExplodedGraph created by executing the simulation.
254
  void ViewGraph(bool trim = false);
255
 
256
  /// Visualize a trimmed ExplodedGraph that only contains paths to the given
257
  /// nodes.
258
  void ViewGraph(ArrayRef<const ExplodedNode *> Nodes);
259
 
260
  /// getInitialState - Return the initial state used for the root vertex
261
  ///  in the ExplodedGraph.
262
  ProgramStateRef getInitialState(const LocationContext *InitLoc);
263
 
264
  ExplodedGraph &getGraph() { return G; }
265
  const ExplodedGraph &getGraph() const { return G; }
266
 
267
  /// Run the analyzer's garbage collection - remove dead symbols and
268
  /// bindings from the state.
269
  ///
270
  /// Checkers can participate in this process with two callbacks:
271
  /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
272
  /// class for more information.
273
  ///
274
  /// \param Node The predecessor node, from which the processing should start.
275
  /// \param Out The returned set of output nodes.
276
  /// \param ReferenceStmt The statement which is about to be processed.
277
  ///        Everything needed for this statement should be considered live.
278
  ///        A null statement means that everything in child LocationContexts
279
  ///        is dead.
280
  /// \param LC The location context of the \p ReferenceStmt. A null location
281
  ///        context means that we have reached the end of analysis and that
282
  ///        all statements and local variables should be considered dead.
283
  /// \param DiagnosticStmt Used as a location for any warnings that should
284
  ///        occur while removing the dead (e.g. leaks). By default, the
285
  ///        \p ReferenceStmt is used.
286
  /// \param K Denotes whether this is a pre- or post-statement purge. This
287
  ///        must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
288
  ///        entire location context is being cleared, in which case the
289
  ///        \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
290
  ///        it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
291
  ///        and \p ReferenceStmt must be valid (non-null).
292
  void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
293
            const Stmt *ReferenceStmt, const LocationContext *LC,
294
            const Stmt *DiagnosticStmt = nullptr,
295
            ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
296
 
297
  /// processCFGElement - Called by CoreEngine. Used to generate new successor
298
  ///  nodes by processing the 'effects' of a CFG element.
299
  void processCFGElement(const CFGElement E, ExplodedNode *Pred,
300
                         unsigned StmtIdx, NodeBuilderContext *Ctx);
301
 
302
  void ProcessStmt(const Stmt *S, ExplodedNode *Pred);
303
 
304
  void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
305
 
306
  void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
307
 
308
  void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
309
 
310
  void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
311
 
312
  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
313
                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
314
  void ProcessDeleteDtor(const CFGDeleteDtor D,
315
                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
316
  void ProcessBaseDtor(const CFGBaseDtor D,
317
                       ExplodedNode *Pred, ExplodedNodeSet &Dst);
318
  void ProcessMemberDtor(const CFGMemberDtor D,
319
                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
320
  void ProcessTemporaryDtor(const CFGTemporaryDtor D,
321
                            ExplodedNode *Pred, ExplodedNodeSet &Dst);
322
 
323
  /// Called by CoreEngine when processing the entrance of a CFGBlock.
324
  void processCFGBlockEntrance(const BlockEdge &L,
325
                               NodeBuilderWithSinks &nodeBuilder,
326
                               ExplodedNode *Pred);
327
 
328
  /// ProcessBranch - Called by CoreEngine.  Used to generate successor
329
  ///  nodes by processing the 'effects' of a branch condition.
330
  void processBranch(const Stmt *Condition,
331
                     NodeBuilderContext& BuilderCtx,
332
                     ExplodedNode *Pred,
333
                     ExplodedNodeSet &Dst,
334
                     const CFGBlock *DstT,
335
                     const CFGBlock *DstF);
336
 
337
  /// Called by CoreEngine.
338
  /// Used to generate successor nodes for temporary destructors depending
339
  /// on whether the corresponding constructor was visited.
340
  void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
341
                                     NodeBuilderContext &BldCtx,
342
                                     ExplodedNode *Pred, ExplodedNodeSet &Dst,
343
                                     const CFGBlock *DstT,
344
                                     const CFGBlock *DstF);
345
 
346
  /// Called by CoreEngine.  Used to processing branching behavior
347
  /// at static initializers.
348
  void processStaticInitializer(const DeclStmt *DS,
349
                                NodeBuilderContext& BuilderCtx,
350
                                ExplodedNode *Pred,
351
                                ExplodedNodeSet &Dst,
352
                                const CFGBlock *DstT,
353
                                const CFGBlock *DstF);
354
 
355
  /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
356
  ///  nodes by processing the 'effects' of a computed goto jump.
357
  void processIndirectGoto(IndirectGotoNodeBuilder& builder);
358
 
359
  /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
360
  ///  nodes by processing the 'effects' of a switch statement.
361
  void processSwitch(SwitchNodeBuilder& builder);
362
 
363
  /// Called by CoreEngine.  Used to notify checkers that processing a
364
  /// function has begun. Called for both inlined and top-level functions.
365
  void processBeginOfFunction(NodeBuilderContext &BC,
366
                              ExplodedNode *Pred, ExplodedNodeSet &Dst,
367
                              const BlockEdge &L);
368
 
369
  /// Called by CoreEngine.  Used to notify checkers that processing a
370
  /// function has ended. Called for both inlined and top-level functions.
371
  void processEndOfFunction(NodeBuilderContext& BC,
372
                            ExplodedNode *Pred,
373
                            const ReturnStmt *RS = nullptr);
374
 
375
  /// Remove dead bindings/symbols before exiting a function.
376
  void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
377
                                 ExplodedNode *Pred,
378
                                 ExplodedNodeSet &Dst);
379
 
380
  /// Generate the entry node of the callee.
381
  void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
382
                        ExplodedNode *Pred);
383
 
384
  /// Generate the sequence of nodes that simulate the call exit and the post
385
  /// visit for CallExpr.
386
  void processCallExit(ExplodedNode *Pred);
387
 
388
  /// Called by CoreEngine when the analysis worklist has terminated.
389
  void processEndWorklist();
390
 
391
  /// evalAssume - Callback function invoked by the ConstraintManager when
392
  ///  making assumptions about state values.
393
  ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
394
                                bool assumption);
395
 
396
  /// processRegionChanges - Called by ProgramStateManager whenever a change is made
397
  ///  to the store. Used to update checkers that track region values.
398
  ProgramStateRef
399
  processRegionChanges(ProgramStateRef state,
400
                       const InvalidatedSymbols *invalidated,
401
                       ArrayRef<const MemRegion *> ExplicitRegions,
402
                       ArrayRef<const MemRegion *> Regions,
403
                       const LocationContext *LCtx,
404
                       const CallEvent *Call);
405
 
406
  inline ProgramStateRef
407
  processRegionChange(ProgramStateRef state,
408
                      const MemRegion* MR,
409
                      const LocationContext *LCtx) {
410
    return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
411
  }
412
 
413
  /// printJson - Called by ProgramStateManager to print checker-specific data.
414
  void printJson(raw_ostream &Out, ProgramStateRef State,
415
                 const LocationContext *LCtx, const char *NL,
416
                 unsigned int Space, bool IsDot) const;
417
 
418
  ProgramStateManager &getStateManager() { return StateMgr; }
419
 
420
  StoreManager &getStoreManager() { return StateMgr.getStoreManager(); }
421
 
422
  ConstraintManager &getConstraintManager() {
423
    return StateMgr.getConstraintManager();
424
  }
425
 
426
  // FIXME: Remove when we migrate over to just using SValBuilder.
427
  BasicValueFactory &getBasicVals() {
428
    return StateMgr.getBasicVals();
429
  }
430
 
431
  SymbolManager &getSymbolManager() { return SymMgr; }
432
  MemRegionManager &getRegionManager() { return MRMgr; }
433
 
434
  DataTag::Factory &getDataTags() { return Engine.getDataTags(); }
435
 
436
  // Functions for external checking of whether we have unfinished work
437
  bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
438
  bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
439
  bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
440
 
441
  const CoreEngine &getCoreEngine() const { return Engine; }
442
 
443
public:
444
  /// Visit - Transfer function logic for all statements.  Dispatches to
445
  ///  other functions that handle specific kinds of statements.
446
  void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
447
 
448
  /// VisitArrayInitLoopExpr - Transfer function for array init loop.
449
  void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred,
450
                              ExplodedNodeSet &Dst);
451
 
452
  /// VisitArraySubscriptExpr - Transfer function for array accesses.
453
  void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex,
454
                               ExplodedNode *Pred,
455
                               ExplodedNodeSet &Dst);
456
 
457
  /// VisitGCCAsmStmt - Transfer function logic for inline asm.
458
  void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
459
                       ExplodedNodeSet &Dst);
460
 
461
  /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
462
  void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
463
                      ExplodedNodeSet &Dst);
464
 
465
  /// VisitBlockExpr - Transfer function logic for BlockExprs.
466
  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
467
                      ExplodedNodeSet &Dst);
468
 
469
  /// VisitLambdaExpr - Transfer function logic for LambdaExprs.
470
  void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
471
                       ExplodedNodeSet &Dst);
472
 
473
  /// VisitBinaryOperator - Transfer function logic for binary operators.
474
  void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred,
475
                           ExplodedNodeSet &Dst);
476
 
477
 
478
  /// VisitCall - Transfer function for function calls.
479
  void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
480
                     ExplodedNodeSet &Dst);
481
 
482
  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
483
  void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
484
                 ExplodedNodeSet &Dst);
485
 
486
  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
487
  void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
488
                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
489
 
490
  /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
491
  void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
492
                              ExplodedNode *Pred, ExplodedNodeSet &Dst);
493
 
494
  /// VisitDeclStmt - Transfer function logic for DeclStmts.
495
  void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
496
                     ExplodedNodeSet &Dst);
497
 
498
  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
499
  void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
500
                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
501
 
502
  void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
503
                         ExplodedNodeSet &Dst);
504
 
505
  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
506
  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
507
                        ExplodedNodeSet &Dst);
508
 
509
  /// VisitMemberExpr - Transfer function for member expressions.
510
  void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
511
                       ExplodedNodeSet &Dst);
512
 
513
  /// VisitAtomicExpr - Transfer function for builtin atomic expressions
514
  void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred,
515
                       ExplodedNodeSet &Dst);
516
 
517
  /// Transfer function logic for ObjCAtSynchronizedStmts.
518
  void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
519
                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
520
 
521
  /// Transfer function logic for computing the lvalue of an Objective-C ivar.
522
  void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
523
                                ExplodedNodeSet &Dst);
524
 
525
  /// VisitObjCForCollectionStmt - Transfer function logic for
526
  ///  ObjCForCollectionStmt.
527
  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
528
                                  ExplodedNode *Pred, ExplodedNodeSet &Dst);
529
 
530
  void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
531
                        ExplodedNodeSet &Dst);
532
 
533
  /// VisitReturnStmt - Transfer function logic for return statements.
534
  void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
535
                       ExplodedNodeSet &Dst);
536
 
537
  /// VisitOffsetOfExpr - Transfer function for offsetof.
538
  void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
539
                         ExplodedNodeSet &Dst);
540
 
541
  /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
542
  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
543
                                     ExplodedNode *Pred, ExplodedNodeSet &Dst);
544
 
545
  /// VisitUnaryOperator - Transfer function logic for unary operators.
546
  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
547
                          ExplodedNodeSet &Dst);
548
 
549
  /// Handle ++ and -- (both pre- and post-increment).
550
  void VisitIncrementDecrementOperator(const UnaryOperator* U,
551
                                       ExplodedNode *Pred,
552
                                       ExplodedNodeSet &Dst);
553
 
554
  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
555
                                 ExplodedNodeSet &PreVisit,
556
                                 ExplodedNodeSet &Dst);
557
 
558
  void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
559
                         ExplodedNodeSet &Dst);
560
 
561
  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
562
                        ExplodedNodeSet & Dst);
563
 
564
  void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
565
                             ExplodedNodeSet &Dst);
566
 
567
  void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E,
568
                                     ExplodedNode *Pred, ExplodedNodeSet &Dst);
569
 
570
  void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
571
                          const Stmt *S, bool IsBaseDtor,
572
                          ExplodedNode *Pred, ExplodedNodeSet &Dst,
573
                          EvalCallOptions &Options);
574
 
575
  void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
576
                                ExplodedNode *Pred,
577
                                ExplodedNodeSet &Dst);
578
 
579
  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
580
                       ExplodedNodeSet &Dst);
581
 
582
  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
583
                          ExplodedNodeSet &Dst);
584
 
585
  /// Create a C++ temporary object for an rvalue.
586
  void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
587
                                ExplodedNode *Pred,
588
                                ExplodedNodeSet &Dst);
589
 
590
  /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
591
  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
592
  ///  with those assumptions.
593
  void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
594
                         const Expr *Ex);
595
 
596
  static std::pair<const ProgramPointTag *, const ProgramPointTag *>
597
    geteagerlyAssumeBinOpBifurcationTags();
598
 
599
  ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
600
                                      const LocationContext *LCtx, QualType T,
601
                                      QualType ExTy, const CastExpr *CastE,
602
                                      StmtNodeBuilder &Bldr,
603
                                      ExplodedNode *Pred);
604
 
605
  ProgramStateRef handleLVectorSplat(ProgramStateRef state,
606
                                     const LocationContext *LCtx,
607
                                     const CastExpr *CastE,
608
                                     StmtNodeBuilder &Bldr,
609
                                     ExplodedNode *Pred);
610
 
611
  void handleUOExtension(ExplodedNodeSet::iterator I,
612
                         const UnaryOperator* U,
613
                         StmtNodeBuilder &Bldr);
614
 
615
public:
616
  SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
617
                 SVal LHS, SVal RHS, QualType T) {
618
    return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
619
  }
620
 
621
  /// Retreives which element is being constructed in a non-POD type array.
622
  static std::optional<unsigned>
623
  getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
624
                               const LocationContext *LCtx);
625
 
626
  /// Retreives which element is being destructed in a non-POD type array.
627
  static std::optional<unsigned>
628
  getPendingArrayDestruction(ProgramStateRef State,
629
                             const LocationContext *LCtx);
630
 
631
  /// Retreives the size of the array in the pending ArrayInitLoopExpr.
632
  static std::optional<unsigned>
633
  getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E,
634
                     const LocationContext *LCtx);
635
 
636
  /// By looking at a certain item that may be potentially part of an object's
637
  /// ConstructionContext, retrieve such object's location. A particular
638
  /// statement can be transparently passed as \p Item in most cases.
639
  static std::optional<SVal>
640
  getObjectUnderConstruction(ProgramStateRef State,
641
                             const ConstructionContextItem &Item,
642
                             const LocationContext *LC);
643
 
644
  /// Call PointerEscape callback when a value escapes as a result of bind.
645
  ProgramStateRef processPointerEscapedOnBind(
646
      ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals,
647
      const LocationContext *LCtx, PointerEscapeKind Kind,
648
      const CallEvent *Call);
649
 
650
  /// Call PointerEscape callback when a value escapes as a result of
651
  /// region invalidation.
652
  /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
653
  ProgramStateRef notifyCheckersOfPointerEscape(
654
                           ProgramStateRef State,
655
                           const InvalidatedSymbols *Invalidated,
656
                           ArrayRef<const MemRegion *> ExplicitRegions,
657
                           const CallEvent *Call,
658
                           RegionAndSymbolInvalidationTraits &ITraits);
659
 
660
private:
661
  /// evalBind - Handle the semantics of binding a value to a specific location.
662
  ///  This method is used by evalStore, VisitDeclStmt, and others.
663
  void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
664
                SVal location, SVal Val, bool atDeclInit = false,
665
                const ProgramPoint *PP = nullptr);
666
 
667
  ProgramStateRef
668
  processPointerEscapedOnBind(ProgramStateRef State,
669
                              SVal Loc, SVal Val,
670
                              const LocationContext *LCtx);
671
 
672
  /// A simple wrapper when you only need to notify checkers of pointer-escape
673
  /// of some values.
674
  ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef<SVal> Vs,
675
                               PointerEscapeKind K,
676
                               const CallEvent *Call = nullptr) const;
677
 
678
public:
679
  // FIXME: 'tag' should be removed, and a LocationContext should be used
680
  // instead.
681
  // FIXME: Comment on the meaning of the arguments, when 'St' may not
682
  // be the same as Pred->state, and when 'location' may not be the
683
  // same as state->getLValue(Ex).
684
  /// Simulate a read of the result of Ex.
685
  void evalLoad(ExplodedNodeSet &Dst,
686
                const Expr *NodeEx,  /* Eventually will be a CFGStmt */
687
                const Expr *BoundExpr,
688
                ExplodedNode *Pred,
689
                ProgramStateRef St,
690
                SVal location,
691
                const ProgramPointTag *tag = nullptr,
692
                QualType LoadTy = QualType());
693
 
694
  // FIXME: 'tag' should be removed, and a LocationContext should be used
695
  // instead.
696
  void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
697
                 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
698
                 const ProgramPointTag *tag = nullptr);
699
 
700
  /// Return the CFG element corresponding to the worklist element
701
  /// that is currently being processed by ExprEngine.
702
  CFGElement getCurrentCFGElement() {
703
    return (*currBldrCtx->getBlock())[currStmtIdx];
704
  }
705
 
706
  /// Create a new state in which the call return value is binded to the
707
  /// call origin expression.
708
  ProgramStateRef bindReturnValue(const CallEvent &Call,
709
                                  const LocationContext *LCtx,
710
                                  ProgramStateRef State);
711
 
712
  /// Evaluate a call, running pre- and post-call checkers and allowing checkers
713
  /// to be responsible for handling the evaluation of the call itself.
714
  void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
715
                const CallEvent &Call);
716
 
717
  /// Default implementation of call evaluation.
718
  void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
719
                       const CallEvent &Call,
720
                       const EvalCallOptions &CallOpts = {});
721
 
722
  /// Find location of the object that is being constructed by a given
723
  /// constructor. This should ideally always succeed but due to not being
724
  /// fully implemented it sometimes indicates that it failed via its
725
  /// out-parameter CallOpts; in such cases a fake temporary region is
726
  /// returned, which is better than nothing but does not represent
727
  /// the actual behavior of the program. The Idx parameter is used if we
728
  /// construct an array of objects. In that case it points to the index
729
  /// of the continuous memory region.
730
  /// E.g.:
731
  /// For `int arr[4]` this index can be 0,1,2,3.
732
  /// For `int arr2[3][3]` this index can be 0,1,...,7,8.
733
  /// A multi-dimensional array is also a continuous memory location in a
734
  /// row major order, so for arr[0][0] Idx is 0 and for arr[2][2] Idx is 8.
735
  SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
736
                                      const NodeBuilderContext *BldrCtx,
737
                                      const LocationContext *LCtx,
738
                                      const ConstructionContext *CC,
739
                                      EvalCallOptions &CallOpts,
740
                                      unsigned Idx = 0);
741
 
742
  /// Update the program state with all the path-sensitive information
743
  /// that's necessary to perform construction of an object with a given
744
  /// syntactic construction context. V and CallOpts have to be obtained from
745
  /// computeObjectUnderConstruction() invoked with the same set of
746
  /// the remaining arguments (E, State, LCtx, CC).
747
  ProgramStateRef updateObjectsUnderConstruction(
748
      SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
749
      const ConstructionContext *CC, const EvalCallOptions &CallOpts);
750
 
751
  /// A convenient wrapper around computeObjectUnderConstruction
752
  /// and updateObjectsUnderConstruction.
753
  std::pair<ProgramStateRef, SVal> handleConstructionContext(
754
      const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
755
      const LocationContext *LCtx, const ConstructionContext *CC,
756
      EvalCallOptions &CallOpts, unsigned Idx = 0) {
757
 
758
    SVal V = computeObjectUnderConstruction(E, State, BldrCtx, LCtx, CC,
759
                                            CallOpts, Idx);
760
    State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
761
 
762
    return std::make_pair(State, V);
763
  }
764
 
765
private:
766
  ProgramStateRef finishArgumentConstruction(ProgramStateRef State,
767
                                             const CallEvent &Call);
768
  void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
769
                                  const CallEvent &Call);
770
 
771
  void evalLoadCommon(ExplodedNodeSet &Dst,
772
                      const Expr *NodeEx,  /* Eventually will be a CFGStmt */
773
                      const Expr *BoundEx,
774
                      ExplodedNode *Pred,
775
                      ProgramStateRef St,
776
                      SVal location,
777
                      const ProgramPointTag *tag,
778
                      QualType LoadTy);
779
 
780
  void evalLocation(ExplodedNodeSet &Dst,
781
                    const Stmt *NodeEx, /* This will eventually be a CFGStmt */
782
                    const Stmt *BoundEx,
783
                    ExplodedNode *Pred,
784
                    ProgramStateRef St,
785
                    SVal location,
786
                    bool isLoad);
787
 
788
  /// Count the stack depth and determine if the call is recursive.
789
  void examineStackFrames(const Decl *D, const LocationContext *LCtx,
790
                          bool &IsRecursive, unsigned &StackDepth);
791
 
792
  enum CallInlinePolicy {
793
    CIP_Allowed,
794
    CIP_DisallowedOnce,
795
    CIP_DisallowedAlways
796
  };
797
 
798
  /// See if a particular call should be inlined, by only looking
799
  /// at the call event and the current state of analysis.
800
  CallInlinePolicy mayInlineCallKind(const CallEvent &Call,
801
                                     const ExplodedNode *Pred,
802
                                     AnalyzerOptions &Opts,
803
                                     const EvalCallOptions &CallOpts);
804
 
805
  /// See if the given AnalysisDeclContext is built for a function that we
806
  /// should always inline simply because it's small enough.
807
  /// Apart from "small" functions, we also have "large" functions
808
  /// (cf. isLarge()), some of which are huge (cf. isHuge()), and we classify
809
  /// the remaining functions as "medium".
810
  bool isSmall(AnalysisDeclContext *ADC) const;
811
 
812
  /// See if the given AnalysisDeclContext is built for a function that we
813
  /// should inline carefully because it looks pretty large.
814
  bool isLarge(AnalysisDeclContext *ADC) const;
815
 
816
  /// See if the given AnalysisDeclContext is built for a function that we
817
  /// should never inline because it's legit gigantic.
818
  bool isHuge(AnalysisDeclContext *ADC) const;
819
 
820
  /// See if the given AnalysisDeclContext is built for a function that we
821
  /// should inline, just by looking at the declaration of the function.
822
  bool mayInlineDecl(AnalysisDeclContext *ADC) const;
823
 
824
  /// Checks our policies and decides weither the given call should be inlined.
825
  bool shouldInlineCall(const CallEvent &Call, const Decl *D,
826
                        const ExplodedNode *Pred,
827
                        const EvalCallOptions &CallOpts = {});
828
 
829
  /// Checks whether our policies allow us to inline a non-POD type array
830
  /// construction.
831
  bool shouldInlineArrayConstruction(const ProgramStateRef State,
832
                                     const CXXConstructExpr *CE,
833
                                     const LocationContext *LCtx);
834
 
835
  /// Checks whether our policies allow us to inline a non-POD type array
836
  /// destruction.
837
  /// \param Size The size of the array.
838
  bool shouldInlineArrayDestruction(uint64_t Size);
839
 
840
  /// Prepares the program state for array destruction. If no error happens
841
  /// the function binds a 'PendingArrayDestruction' entry to the state, which
842
  /// it returns along with the index. If any error happens (we fail to read
843
  /// the size, the index would be -1, etc.) the function will return the
844
  /// original state along with an index of 0. The actual element count of the
845
  /// array can be accessed by the optional 'ElementCountVal' parameter. \param
846
  /// State The program state. \param Region The memory region where the array
847
  /// is stored. \param ElementTy The type an element in the array. \param LCty
848
  /// The location context. \param ElementCountVal A pointer to an optional
849
  /// SVal. If specified, the size of the array will be returned in it. It can
850
  /// be Unknown.
851
  std::pair<ProgramStateRef, uint64_t> prepareStateForArrayDestruction(
852
      const ProgramStateRef State, const MemRegion *Region,
853
      const QualType &ElementTy, const LocationContext *LCtx,
854
      SVal *ElementCountVal = nullptr);
855
 
856
  /// Checks whether we construct an array of non-POD type, and decides if the
857
  /// constructor should be inkoved once again.
858
  bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
859
                            const LocationContext *LCtx);
860
 
861
  void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
862
                  NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
863
 
864
  void ctuBifurcate(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
865
                    ExplodedNode *Pred, ProgramStateRef State);
866
 
867
  /// Returns true if the CTU analysis is running its second phase.
868
  bool isSecondPhaseCTU() { return IsCTUEnabled && !Engine.getCTUWorkList(); }
869
 
870
  /// Conservatively evaluate call by invalidating regions and binding
871
  /// a conjured return value.
872
  void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
873
                            ExplodedNode *Pred, ProgramStateRef State);
874
 
875
  /// Either inline or process the call conservatively (or both), based
876
  /// on DynamicDispatchBifurcation data.
877
  void BifurcateCall(const MemRegion *BifurReg,
878
                     const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
879
                     ExplodedNode *Pred);
880
 
881
  bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
882
 
883
  /// Models a trivial copy or move constructor or trivial assignment operator
884
  /// call with a simple bind.
885
  void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
886
                          const CallEvent &Call);
887
 
888
  /// If the value of the given expression \p InitWithAdjustments is a NonLoc,
889
  /// copy it into a new temporary object region, and replace the value of the
890
  /// expression with that.
891
  ///
892
  /// If \p Result is provided, the new region will be bound to this expression
893
  /// instead of \p InitWithAdjustments.
894
  ///
895
  /// Returns the temporary region with adjustments into the optional
896
  /// OutRegionWithAdjustments out-parameter if a new region was indeed needed,
897
  /// otherwise sets it to nullptr.
898
  ProgramStateRef createTemporaryRegionIfNeeded(
899
      ProgramStateRef State, const LocationContext *LC,
900
      const Expr *InitWithAdjustments, const Expr *Result = nullptr,
901
      const SubRegion **OutRegionWithAdjustments = nullptr);
902
 
903
  /// Returns a region representing the `Idx`th element of a (possibly
904
  /// multi-dimensional) array, for the purposes of element construction or
905
  /// destruction.
906
  ///
907
  /// On return, \p Ty will be set to the base type of the array.
908
  ///
909
  /// If the type is not an array type at all, the original value is returned.
910
  /// Otherwise the "IsArray" flag is set.
911
  static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
912
                                QualType &Ty, bool &IsArray, unsigned Idx = 0);
913
 
914
  /// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
915
  /// block to find the constructor expression that directly constructed into
916
  /// the storage for this statement. Returns null if the constructor for this
917
  /// statement created a temporary object region rather than directly
918
  /// constructing into an existing region.
919
  const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
920
 
921
  /// Common code that handles either a CXXConstructExpr or a
922
  /// CXXInheritedCtorInitExpr.
923
  void handleConstructor(const Expr *E, ExplodedNode *Pred,
924
                         ExplodedNodeSet &Dst);
925
 
926
public:
927
  /// Note whether this loop has any more iteratios to model. These methods are
928
  /// essentially an interface for a GDM trait. Further reading in
929
  /// ExprEngine::VisitObjCForCollectionStmt().
930
  [[nodiscard]] static ProgramStateRef
931
  setWhetherHasMoreIteration(ProgramStateRef State,
932
                             const ObjCForCollectionStmt *O,
933
                             const LocationContext *LC, bool HasMoreIteraton);
934
 
935
  [[nodiscard]] static ProgramStateRef
936
  removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O,
937
                       const LocationContext *LC);
938
 
939
  [[nodiscard]] static bool hasMoreIteration(ProgramStateRef State,
940
                                             const ObjCForCollectionStmt *O,
941
                                             const LocationContext *LC);
942
 
943
private:
944
  /// Assuming we construct an array of non-POD types, this method allows us
945
  /// to store which element is to be constructed next.
946
  static ProgramStateRef
947
  setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
948
                               const LocationContext *LCtx, unsigned Idx);
949
 
950
  static ProgramStateRef
951
  removeIndexOfElementToConstruct(ProgramStateRef State,
952
                                  const CXXConstructExpr *E,
953
                                  const LocationContext *LCtx);
954
 
955
  /// Assuming we destruct an array of non-POD types, this method allows us
956
  /// to store which element is to be destructed next.
957
  static ProgramStateRef setPendingArrayDestruction(ProgramStateRef State,
958
                                                    const LocationContext *LCtx,
959
                                                    unsigned Idx);
960
 
961
  static ProgramStateRef
962
  removePendingArrayDestruction(ProgramStateRef State,
963
                                const LocationContext *LCtx);
964
 
965
  /// Sets the size of the array in a pending ArrayInitLoopExpr.
966
  static ProgramStateRef setPendingInitLoop(ProgramStateRef State,
967
                                            const CXXConstructExpr *E,
968
                                            const LocationContext *LCtx,
969
                                            unsigned Idx);
970
 
971
  static ProgramStateRef removePendingInitLoop(ProgramStateRef State,
972
                                               const CXXConstructExpr *E,
973
                                               const LocationContext *LCtx);
974
 
975
  static ProgramStateRef
976
  removeStateTraitsUsedForArrayEvaluation(ProgramStateRef State,
977
                                          const CXXConstructExpr *E,
978
                                          const LocationContext *LCtx);
979
 
980
  /// Store the location of a C++ object corresponding to a statement
981
  /// until the statement is actually encountered. For example, if a DeclStmt
982
  /// has CXXConstructExpr as its initializer, the object would be considered
983
  /// to be "under construction" between CXXConstructExpr and DeclStmt.
984
  /// This allows, among other things, to keep bindings to variable's fields
985
  /// made within the constructor alive until its declaration actually
986
  /// goes into scope.
987
  static ProgramStateRef
988
  addObjectUnderConstruction(ProgramStateRef State,
989
                             const ConstructionContextItem &Item,
990
                             const LocationContext *LC, SVal V);
991
 
992
  /// Mark the object sa fully constructed, cleaning up the state trait
993
  /// that tracks objects under construction.
994
  static ProgramStateRef
995
  finishObjectConstruction(ProgramStateRef State,
996
                           const ConstructionContextItem &Item,
997
                           const LocationContext *LC);
998
 
999
  /// If the given expression corresponds to a temporary that was used for
1000
  /// passing into an elidable copy/move constructor and that constructor
1001
  /// was actually elided, track that we also need to elide the destructor.
1002
  static ProgramStateRef elideDestructor(ProgramStateRef State,
1003
                                         const CXXBindTemporaryExpr *BTE,
1004
                                         const LocationContext *LC);
1005
 
1006
  /// Stop tracking the destructor that corresponds to an elided constructor.
1007
  static ProgramStateRef
1008
  cleanupElidedDestructor(ProgramStateRef State,
1009
                          const CXXBindTemporaryExpr *BTE,
1010
                          const LocationContext *LC);
1011
 
1012
  /// Returns true if the given expression corresponds to a temporary that
1013
  /// was constructed for passing into an elidable copy/move constructor
1014
  /// and that constructor was actually elided.
1015
  static bool isDestructorElided(ProgramStateRef State,
1016
                                 const CXXBindTemporaryExpr *BTE,
1017
                                 const LocationContext *LC);
1018
 
1019
  /// Check if all objects under construction have been fully constructed
1020
  /// for the given context range (including FromLC, not including ToLC).
1021
  /// This is useful for assertions. Also checks if elided destructors
1022
  /// were cleaned up.
1023
  static bool areAllObjectsFullyConstructed(ProgramStateRef State,
1024
                                            const LocationContext *FromLC,
1025
                                            const LocationContext *ToLC);
1026
};
1027
 
1028
/// Traits for storing the call processing policy inside GDM.
1029
/// The GDM stores the corresponding CallExpr pointer.
1030
// FIXME: This does not use the nice trait macros because it must be accessible
1031
// from multiple translation units.
1032
struct ReplayWithoutInlining{};
1033
template <>
1034
struct ProgramStateTrait<ReplayWithoutInlining> :
1035
  public ProgramStatePartialTrait<const void*> {
1036
  static void *GDMIndex();
1037
};
1038
 
1039
} // namespace ento
1040
 
1041
} // namespace clang
1042
 
1043
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H