clang 23.0.0git
ExprEngine.h
Go to the documentation of this file.
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"
23#include "clang/Basic/LLVM.h"
37#include "llvm/ADT/ArrayRef.h"
38#include <cassert>
39#include <optional>
40#include <utility>
41
42namespace clang {
43
45class AnalyzerOptions;
46class ASTContext;
47class CFGBlock;
48class CFGElement;
51class CXXCatchStmt;
53class CXXDeleteExpr;
54class CXXNewExpr;
55class CXXThisExpr;
56class Decl;
57class DeclStmt;
58class GCCAsmStmt;
59class LambdaExpr;
60class LocationContext;
62class MSAsmStmt;
63class NamedDecl;
66class ObjCIvarRefExpr;
67class ObjCMessageExpr;
68class ReturnStmt;
69class Stmt;
70
71namespace cross_tu {
72
74
75} // namespace cross_tu
76
77namespace ento {
78
79class AnalysisManager;
81class CallEvent;
82class CheckerManager;
84class ExplodedNodeSet;
85class ExplodedNode;
86class MemRegion;
88class ProgramState;
91class SymbolManager;
92
93/// Hints for figuring out of a call should be inlined during evalCall().
95 /// This call is a constructor or a destructor for which we do not currently
96 /// compute the this-region correctly.
98
99 /// This call is a constructor or a destructor for a single element within
100 /// an array, a part of array construction or destruction.
101 bool IsArrayCtorOrDtor = false;
102
103 /// This call is a constructor or a destructor of a temporary value.
105
106 /// This call is a constructor for a temporary that is lifetime-extended
107 /// by binding it to a reference-type field within an aggregate,
108 /// for example 'A { const C &c; }; A a = { C() };'
110
111 /// This call is a pre-C++17 elidable constructor that we failed to elide
112 /// because we failed to compute the target region into which
113 /// this constructor would have been ultimately elided. Analysis that
114 /// we perform in this case is still correct but it behaves differently,
115 /// as if copy elision is disabled.
117
119};
120
122 void anchor();
123
124public:
125 /// The modes of inlining, which override the default analysis-wide settings.
127 /// Follow the default settings for inlining callees.
129
130 /// Do minimal inlining of callees.
132 };
133
134private:
136 bool IsCTUEnabled;
137
138 AnalysisManager &AMgr;
139
140 AnalysisDeclContextManager &AnalysisDeclContexts;
141
142 CoreEngine Engine;
143
144 /// G - the simulation graph.
145 ExplodedGraph &G;
146
147 /// StateMgr - Object that manages the data for all created states.
148 ProgramStateManager StateMgr;
149
150 /// SymMgr - Object that manages the symbol information.
151 SymbolManager &SymMgr;
152
153 /// MRMgr - MemRegionManager object that creates memory regions.
154 MemRegionManager &MRMgr;
155
156 /// svalBuilder - SValBuilder object that creates SVals from expressions.
157 SValBuilder &svalBuilder;
158
159 unsigned int currStmtIdx = 0;
160
161 /// Pointer to a (so-called, somewhat misnamed) NodeBuilderContext object
162 /// which has three independent roles:
163 /// - It holds a pointer to the CFGBlock that is currently under analysis.
164 /// (This is the primary way to get the current block.)
165 /// - It holds a pointer to the current LocationContext. (This is rarely
166 /// used, the location context is usually queried from a recent
167 /// ExplodedNode. Unfortunately it seems that these two sources of truth
168 /// are not always consistent.)
169 /// - It can be used for constructing `NodeBuilder`s. Practically all
170 /// `NodeBuilder` objects are useless complications in the code, so I
171 /// intend to replace them with direct use of `CoreEngine::makeNode`.
172 /// TODO: Eventually `currBldrCtx` should be replaced by two separate fields:
173 /// `const CFGBlock *CurrBlock` & `const LocationContext *CurrLocationContext`
174 /// that are kept up-to-date and are almost always non-null during the
175 /// analysis. I will switch to this more natural representation when
176 /// `NodeBuilder`s are eliminated from the code.
177 const NodeBuilderContext *currBldrCtx = nullptr;
178 /// Historically `currBldrCtx` pointed to a local variable in some stack
179 /// frame. This field is introduced as a temporary measure to allow a gradual
180 /// transition. Only use this in {re,}setLocationContextAndBlock!
181 /// TODO: Remove this temporary hack.
182 std::optional<NodeBuilderContext> OwnedCurrBldrCtx;
183
184 /// Helper object to determine if an Objective-C message expression
185 /// implicitly never returns.
186 ObjCNoReturn ObjCNoRet;
187
188 /// The BugReporter associated with this engine. It is important that
189 /// this object be placed at the very end of member variables so that its
190 /// destructor is called before the rest of the ExprEngine is destroyed.
192
193 /// The functions which have been analyzed through inlining. This is owned by
194 /// AnalysisConsumer. It can be null.
195 SetOfConstDecls *VisitedCallees;
196
197 /// The flag, which specifies the mode of inlining for the engine.
198 InliningModes HowToInline;
199
200public:
202 SetOfConstDecls *VisitedCalleesIn,
203 FunctionSummariesTy *FS, InliningModes HowToInlineIn);
204
205 virtual ~ExprEngine() = default;
206
207 /// Returns true if there is still simulation state on the worklist.
208 bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
209 assert(L->inTopFrame());
210 BR.setAnalysisEntryPoint(L->getDecl());
211 return Engine.ExecuteWorkList(L, Steps, nullptr);
212 }
213
214 /// getContext - Return the ASTContext associated with this analysis.
215 ASTContext &getContext() const { return AMgr.getASTContext(); }
216
218 const AnalysisManager &getAnalysisManager() const { return AMgr; }
219
221 return AMgr.getAnalysisDeclContextManager();
222 }
223
225 return *AMgr.getCheckerManager();
226 }
227
228 SValBuilder &getSValBuilder() { return svalBuilder; }
229 const SValBuilder &getSValBuilder() const { return svalBuilder; }
230
231 BugReporter &getBugReporter() { return BR; }
232 const BugReporter &getBugReporter() const { return BR; }
233
236 return &CTU;
237 }
238
239 // FIXME: Ideally the body of this method should look like
240 // CurrLocationContext = LC;
241 // CurrBlock = B;
242 // where CurrLocationContext and CurrBlock are new member variables that
243 // fulfill the roles of `currBldrCtx` in a more natural way.
244 // This implementation is a temporary measure to allow a gradual transition.
246 const CFGBlock *B) {
247 // The current LocationContext and Block is reset at the beginning of
248 // dispacthWorkItem. Ideally, this method should be called only once per
249 // dipatchWorkItem call (= elementary analysis step); so the following
250 // assertion is there to catch accidental repeated calls. If the current
251 // LocationContext and Block needs to change in the middle of a single step
252 // (which currently happens only once, in processCallExit), use an explicit
253 // call to resetCurrLocationContextAndBlock.
254 assert(!currBldrCtx && !OwnedCurrBldrCtx &&
255 "The current LocationContext and Block is already set");
256 OwnedCurrBldrCtx.emplace(Engine, B, LC);
257 currBldrCtx = &*OwnedCurrBldrCtx;
258 }
259
261 currBldrCtx = nullptr;
262 OwnedCurrBldrCtx = std::nullopt;
263 }
264
266 assert(currBldrCtx);
267 return *currBldrCtx;
268 }
269
271 assert(G.getRoot());
272 return G.getRoot()->getLocation().getLocationContext();
273 }
274
275 /// Get the 'current' location context corresponding to the current work item
276 /// (elementary analysis step handled by `dispatchWorkItem`).
277 /// FIXME: This sometimes (e.g. in some `BeginFunction` callbacks) differs
278 /// from the `LocationContext` that can be obtained from different sources
279 /// (e.g. a recent `ExplodedNode`). Traditionally this location context is
280 /// only used for block count calculations (`getNumVisited`); it is probably
281 /// wise to follow this tradition until the discrepancies are resolved.
283 return currBldrCtx ? currBldrCtx->getLocationContext() : nullptr;
284 }
285
286 /// Get the 'current' CFGBlock corresponding to the current work item
287 /// (elementary analysis step handled by `dispatchWorkItem`).
288 const CFGBlock *getCurrBlock() const {
289 return currBldrCtx ? currBldrCtx->getBlock() : nullptr;
290 }
291
293 return {getCurrBlock(), currStmtIdx};
294 }
295
296 unsigned getNumVisited(const LocationContext *LC,
297 const CFGBlock *Block) const {
298 return Engine.WList->getBlockCounter().getNumVisited(LC->getStackFrame(),
299 Block->getBlockID());
300 }
301
302 unsigned getNumVisitedCurrent() const {
304 }
305
306 /// Dump graph to the specified filename.
307 /// If filename is empty, generate a temporary one.
308 /// \return The filename the graph is written into.
309 std::string DumpGraph(bool trim = false, StringRef Filename="");
310
311 /// Dump the graph consisting of the given nodes to a specified filename.
312 /// Generate a temporary filename if it's not provided.
313 /// \return The filename the graph is written into.
315 StringRef Filename = "");
316
317 /// Visualize the ExplodedGraph created by executing the simulation.
318 void ViewGraph(bool trim = false);
319
320 /// Visualize a trimmed ExplodedGraph that only contains paths to the given
321 /// nodes.
323
324 /// getInitialState - Return the initial state used for the root vertex
325 /// in the ExplodedGraph.
327
328 ExplodedGraph &getGraph() { return G; }
329 const ExplodedGraph &getGraph() const { return G; }
330
331 /// Run the analyzer's garbage collection - remove dead symbols and
332 /// bindings from the state.
333 ///
334 /// Checkers can participate in this process with two callbacks:
335 /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
336 /// class for more information.
337 ///
338 /// \param Node The predecessor node, from which the processing should start.
339 /// \param Out The returned set of output nodes.
340 /// \param ReferenceStmt The statement which is about to be processed.
341 /// Everything needed for this statement should be considered live.
342 /// A null statement means that everything in child LocationContexts
343 /// is dead.
344 /// \param LC The location context of the \p ReferenceStmt. A null location
345 /// context means that we have reached the end of analysis and that
346 /// all statements and local variables should be considered dead.
347 /// \param DiagnosticStmt Used as a location for any warnings that should
348 /// occur while removing the dead (e.g. leaks). By default, the
349 /// \p ReferenceStmt is used.
350 /// \param K Denotes whether this is a pre- or post-statement purge. This
351 /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
352 /// entire location context is being cleared, in which case the
353 /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
354 /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
355 /// and \p ReferenceStmt must be valid (non-null).
356 void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
357 const Stmt *ReferenceStmt, const LocationContext *LC,
358 const Stmt *DiagnosticStmt = nullptr,
360
361 /// A tag to track convenience transitions, which can be removed at cleanup.
362 /// This tag applies to a node created after removeDead.
363 static const ProgramPointTag *cleanupNodeTag();
364
365 /// processCFGElement - Called by CoreEngine. Used to generate new successor
366 /// nodes by processing the 'effects' of a CFG element.
367 void processCFGElement(const CFGElement E, ExplodedNode *Pred,
368 unsigned StmtIdx);
369
370 void ProcessStmt(const Stmt *S, ExplodedNode *Pred);
371
372 void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
373
375
377
378 void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
379
381 ExplodedNode *Pred, ExplodedNodeSet &Dst);
382 void ProcessDeleteDtor(const CFGDeleteDtor D,
383 ExplodedNode *Pred, ExplodedNodeSet &Dst);
384 void ProcessBaseDtor(const CFGBaseDtor D,
385 ExplodedNode *Pred, ExplodedNodeSet &Dst);
386 void ProcessMemberDtor(const CFGMemberDtor D,
387 ExplodedNode *Pred, ExplodedNodeSet &Dst);
389 ExplodedNode *Pred, ExplodedNodeSet &Dst);
390
391 /// Called by CoreEngine when processing the entrance of a CFGBlock.
392 void processCFGBlockEntrance(const BlockEdge &L, const BlockEntrance &BE,
393 NodeBuilder &Builder, ExplodedNode *Pred);
394
395 void runCheckersForBlockEntrance(const BlockEntrance &Entrance,
396 ExplodedNode *Pred, ExplodedNodeSet &Dst);
397
398 /// ProcessBranch - Called by CoreEngine. Used to generate successor nodes by
399 /// processing the 'effects' of a branch condition. If the branch condition
400 /// is a loop condition, IterationsCompletedInLoop is the number of completed
401 /// iterations (otherwise it's std::nullopt).
402 void processBranch(const Stmt *Condition, ExplodedNode *Pred,
403 ExplodedNodeSet &Dst, const CFGBlock *DstT,
404 const CFGBlock *DstF,
405 std::optional<unsigned> IterationsCompletedInLoop);
406
407 /// Called by CoreEngine.
408 /// Used to generate successor nodes for temporary destructors depending
409 /// on whether the corresponding constructor was visited.
411 ExplodedNode *Pred, ExplodedNodeSet &Dst,
412 const CFGBlock *DstT,
413 const CFGBlock *DstF);
414
415 /// Called by CoreEngine. Used to processing branching behavior
416 /// at static initializers.
418 ExplodedNodeSet &Dst, const CFGBlock *DstT,
419 const CFGBlock *DstF);
420
421 /// processIndirectGoto - Called by CoreEngine. Used to generate successor
422 /// nodes by processing the 'effects' of a computed goto jump.
423 void processIndirectGoto(ExplodedNodeSet &Dst, const Expr *Tgt,
424 const CFGBlock *Dispatch, ExplodedNode *Pred);
425
426 /// ProcessSwitch - Called by CoreEngine. Used to generate successor
427 /// nodes by processing the 'effects' of a switch statement.
428 void processSwitch(const SwitchStmt *Switch, ExplodedNode *Pred,
429 ExplodedNodeSet &Dst);
430
431 /// Called by CoreEngine. Used to notify checkers that processing a
432 /// function has begun. Called for both inlined and top-level functions.
434 const BlockEdge &L);
435
436 /// Called by CoreEngine. Used to notify checkers that processing a
437 /// function has ended. Called for both inlined and top-level functions.
438 void processEndOfFunction(ExplodedNode *Pred, const ReturnStmt *RS = nullptr);
439
440 /// Remove dead bindings/symbols before exiting a function.
442
443 /// Generate the entry node of the callee.
445
446 /// Generate the sequence of nodes that simulate the call exit and the post
447 /// visit for CallExpr.
448 void processCallExit(ExplodedNode *Pred);
449
450 /// Called by CoreEngine when the analysis worklist has terminated.
451 void processEndWorklist();
452
453 /// evalAssume - Callback function invoked by the ConstraintManager when
454 /// making assumptions about state values.
456 bool assumption);
457
458 /// processRegionChanges - Called by ProgramStateManager whenever a change is made
459 /// to the store. Used to update checkers that track region values.
462 const InvalidatedSymbols *invalidated,
463 ArrayRef<const MemRegion *> ExplicitRegions,
465 const LocationContext *LCtx,
466 const CallEvent *Call);
467
468 inline ProgramStateRef
470 const MemRegion* MR,
471 const LocationContext *LCtx) {
472 return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
473 }
474
475 /// printJson - Called by ProgramStateManager to print checker-specific data.
476 void printJson(raw_ostream &Out, ProgramStateRef State,
477 const LocationContext *LCtx, const char *NL,
478 unsigned int Space, bool IsDot) const;
479
480 ProgramStateManager &getStateManager() { return StateMgr; }
481 const ProgramStateManager &getStateManager() const { return StateMgr; }
482
483 StoreManager &getStoreManager() { return StateMgr.getStoreManager(); }
485 return StateMgr.getStoreManager();
486 }
487
489 return StateMgr.getConstraintManager();
490 }
492 return StateMgr.getConstraintManager();
493 }
494
495 // FIXME: Remove when we migrate over to just using SValBuilder.
497 return StateMgr.getBasicVals();
498 }
499
500 SymbolManager &getSymbolManager() { return SymMgr; }
501 const SymbolManager &getSymbolManager() const { return SymMgr; }
503
504 DataTag::Factory &getDataTags() { return Engine.getDataTags(); }
505
506 // Functions for external checking of whether we have unfinished work.
507 bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
508 bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
509 bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
510
511 const CoreEngine &getCoreEngine() const { return Engine; }
512
513public:
514 /// Visit - Transfer function logic for all statements. Dispatches to
515 /// other functions that handle specific kinds of statements.
516 void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
517
518 /// VisitArrayInitLoopExpr - Transfer function for array init loop.
520 ExplodedNodeSet &Dst);
521
522 /// VisitArraySubscriptExpr - Transfer function for array accesses.
524 ExplodedNode *Pred,
525 ExplodedNodeSet &Dst);
526
527 /// VisitGCCAsmStmt - Transfer function logic for inline asm.
528 void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
529 ExplodedNodeSet &Dst);
530
531 /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
532 void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
533 ExplodedNodeSet &Dst);
534
535 /// VisitBlockExpr - Transfer function logic for BlockExprs.
536 void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
537 ExplodedNodeSet &Dst);
538
539 /// VisitLambdaExpr - Transfer function logic for LambdaExprs.
540 void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
541 ExplodedNodeSet &Dst);
542
543 /// VisitBinaryOperator - Transfer function logic for binary operators.
545 ExplodedNodeSet &Dst);
546
547
548 /// VisitCall - Transfer function for function calls.
549 void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
550 ExplodedNodeSet &Dst);
551
552 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
553 void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
554 ExplodedNodeSet &Dst);
555
556 /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
558 ExplodedNode *Pred, ExplodedNodeSet &Dst);
559
560 /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
561 void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
562 ExplodedNode *Pred, ExplodedNodeSet &Dst);
563
564 /// VisitDeclStmt - Transfer function logic for DeclStmts.
565 void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
566 ExplodedNodeSet &Dst);
567
568 /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
569 void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
570 ExplodedNode *Pred, ExplodedNodeSet &Dst);
571
572 /// VisitAttributedStmt - Transfer function logic for AttributedStmt.
574 ExplodedNodeSet &Dst);
575
576 /// VisitLogicalExpr - Transfer function logic for '&&', '||'.
577 void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
578 ExplodedNodeSet &Dst);
579
580 /// VisitMemberExpr - Transfer function for member expressions.
581 void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
582 ExplodedNodeSet &Dst);
583
584 /// VisitAtomicExpr - Transfer function for builtin atomic expressions.
585 void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred,
586 ExplodedNodeSet &Dst);
587
588 /// Transfer function logic for ObjCAtSynchronizedStmts.
590 ExplodedNode *Pred, ExplodedNodeSet &Dst);
591
592 /// Transfer function logic for computing the lvalue of an Objective-C ivar.
594 ExplodedNodeSet &Dst);
595
596 /// VisitObjCForCollectionStmt - Transfer function logic for
597 /// ObjCForCollectionStmt.
599 ExplodedNode *Pred, ExplodedNodeSet &Dst);
600
601 void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
602 ExplodedNodeSet &Dst);
603
604 /// VisitReturnStmt - Transfer function logic for return statements.
605 void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
606 ExplodedNodeSet &Dst);
607
608 /// VisitOffsetOfExpr - Transfer function for offsetof.
609 void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
610 ExplodedNodeSet &Dst);
611
612 /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
614 ExplodedNode *Pred, ExplodedNodeSet &Dst);
615
616 /// VisitUnaryOperator - Transfer function logic for unary operators.
617 void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
618 ExplodedNodeSet &Dst);
619
620 /// Handle ++ and -- (both pre- and post-increment).
622 ExplodedNode *Pred,
623 ExplodedNodeSet &Dst);
624
626 ExplodedNodeSet &PreVisit,
627 ExplodedNodeSet &Dst);
628
629 void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
630 ExplodedNodeSet &Dst);
631
632 void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
633 ExplodedNodeSet & Dst);
634
636 ExplodedNodeSet &Dst);
637
639 ExplodedNode *Pred, ExplodedNodeSet &Dst);
640
641 void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
642 const Stmt *S, bool IsBaseDtor,
643 ExplodedNode *Pred, ExplodedNodeSet &Dst,
644 EvalCallOptions &Options);
645
646 void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
647 ExplodedNode *Pred,
648 ExplodedNodeSet &Dst);
649
650 void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
651 ExplodedNodeSet &Dst);
652
654 ExplodedNodeSet &Dst);
655
656 /// Create a C++ temporary object for an rvalue.
658 ExplodedNode *Pred,
659 ExplodedNodeSet &Dst);
660
661 void ConstructInitList(const Expr *Source, ArrayRef<Expr *> Args,
662 bool IsTransparent, ExplodedNode *Pred,
663 ExplodedNodeSet &Dst);
664
665 /// evalEagerlyAssumeBifurcation - Given the nodes in 'Src', eagerly assume
666 /// concrete boolean values for 'Ex', storing the resulting nodes in 'Dst'.
668 const Expr *Ex);
669
670 bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const;
671
672 static std::pair<const ProgramPointTag *, const ProgramPointTag *>
674
676 const LocationContext *LCtx, QualType T,
677 QualType ExTy, const CastExpr *CastE,
678 NodeBuilder &Bldr, ExplodedNode *Pred);
679
681 NodeBuilder &Bldr);
682
683public:
685 SVal LHS, SVal RHS, QualType T) {
686 return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
687 }
688
689 /// Retreives which element is being constructed in a non-POD type array.
690 static std::optional<unsigned>
692 const LocationContext *LCtx);
693
694 /// Retreives which element is being destructed in a non-POD type array.
695 static std::optional<unsigned>
697 const LocationContext *LCtx);
698
699 /// Retreives the size of the array in the pending ArrayInitLoopExpr.
700 static std::optional<unsigned>
702 const LocationContext *LCtx);
703
704 /// By looking at a certain item that may be potentially part of an object's
705 /// ConstructionContext, retrieve such object's location. A particular
706 /// statement can be transparently passed as \p Item in most cases.
707 static std::optional<SVal>
709 const ConstructionContextItem &Item,
710 const LocationContext *LC);
711
712 /// Call PointerEscape callback when a value escapes as a result of bind.
714 ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals,
715 const LocationContext *LCtx, PointerEscapeKind Kind,
716 const CallEvent *Call);
717
718 /// Call PointerEscape callback when a value escapes as a result of
719 /// region invalidation.
720 /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
722 ProgramStateRef State,
723 const InvalidatedSymbols *Invalidated,
724 ArrayRef<const MemRegion *> ExplicitRegions,
725 const CallEvent *Call,
727
728private:
729 /// evalBind - Handle the semantics of binding a value to a specific location.
730 /// This method is used by evalStore, VisitDeclStmt, and others.
731 void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
732 SVal location, SVal Val, bool AtDeclInit = false,
733 const ProgramPoint *PP = nullptr);
734
737 SVal Loc, SVal Val,
738 const LocationContext *LCtx);
739
740public:
741 /// A simple wrapper when you only need to notify checkers of pointer-escape
742 /// of some values.
745 const CallEvent *Call = nullptr) const;
746
747 // FIXME: 'tag' should be removed, and a LocationContext should be used
748 // instead.
749 // FIXME: Comment on the meaning of the arguments, when 'St' may not
750 // be the same as Pred->state, and when 'location' may not be the
751 // same as state->getLValue(Ex).
752 /// Simulate a read of the result of Ex.
753 void evalLoad(ExplodedNodeSet &Dst,
754 const Expr *NodeEx, /* Eventually will be a CFGStmt */
755 const Expr *BoundExpr,
756 ExplodedNode *Pred,
758 SVal location,
759 const ProgramPointTag *tag = nullptr,
760 QualType LoadTy = QualType());
761
762 // FIXME: 'tag' should be removed, and a LocationContext should be used
763 // instead.
764 void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
765 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
766 const ProgramPointTag *tag = nullptr);
767
768 /// Return the CFG element corresponding to the worklist element
769 /// that is currently being processed by ExprEngine.
770 CFGElement getCurrentCFGElement() { return (*getCurrBlock())[currStmtIdx]; }
771
772 /// Create a new state in which the call return value is binded to the
773 /// call origin expression.
775 const LocationContext *LCtx,
776 ProgramStateRef State);
777
778 /// Evaluate a call, running pre- and post-call checkers and allowing checkers
779 /// to be responsible for handling the evaluation of the call itself.
780 void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
781 const CallEvent &Call);
782
783 /// Default implementation of call evaluation.
785 const CallEvent &Call,
786 const EvalCallOptions &CallOpts = {});
787
788 /// Find location of the object that is being constructed by a given
789 /// constructor. This should ideally always succeed but due to not being
790 /// fully implemented it sometimes indicates that it failed via its
791 /// out-parameter CallOpts; in such cases a fake temporary region is
792 /// returned, which is better than nothing but does not represent
793 /// the actual behavior of the program. The Idx parameter is used if we
794 /// construct an array of objects. In that case it points to the index
795 /// of the continuous memory region.
796 /// E.g.:
797 /// For `int arr[4]` this index can be 0,1,2,3.
798 /// For `int arr2[3][3]` this index can be 0,1,...,7,8.
799 /// A multi-dimensional array is also a continuous memory location in a
800 /// row major order, so for arr[0][0] Idx is 0 and for arr[3][3] Idx is 8.
802 unsigned NumVisitedCaller,
803 const LocationContext *LCtx,
804 const ConstructionContext *CC,
805 EvalCallOptions &CallOpts,
806 unsigned Idx = 0);
807
808 /// Update the program state with all the path-sensitive information
809 /// that's necessary to perform construction of an object with a given
810 /// syntactic construction context. V and CallOpts have to be obtained from
811 /// computeObjectUnderConstruction() invoked with the same set of
812 /// the remaining arguments (E, State, LCtx, CC).
814 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
815 const ConstructionContext *CC, const EvalCallOptions &CallOpts);
816
817 /// A convenient wrapper around computeObjectUnderConstruction
818 /// and updateObjectsUnderConstruction.
819 std::pair<ProgramStateRef, SVal> handleConstructionContext(
820 const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
821 const LocationContext *LCtx, const ConstructionContext *CC,
822 EvalCallOptions &CallOpts, unsigned Idx = 0) {
823
824 SVal V = computeObjectUnderConstruction(E, State, BldrCtx->blockCount(),
825 LCtx, CC, CallOpts, Idx);
826 State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
827
828 return std::make_pair(State, V);
829 }
830
831private:
832 ProgramStateRef finishArgumentConstruction(ProgramStateRef State,
833 const CallEvent &Call);
834 void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
835 const CallEvent &Call);
836
837 void evalLocation(ExplodedNodeSet &Dst,
838 const Stmt *NodeEx, /* This will eventually be a CFGStmt */
839 const Stmt *BoundEx,
840 ExplodedNode *Pred,
842 SVal location,
843 bool isLoad);
844
845 /// Count the stack depth and determine if the call is recursive.
846 void examineStackFrames(const Decl *D, const LocationContext *LCtx,
847 bool &IsRecursive, unsigned &StackDepth);
848
849 enum CallInlinePolicy {
850 CIP_Allowed,
851 CIP_DisallowedOnce,
852 CIP_DisallowedAlways
853 };
854
855 /// See if a particular call should be inlined, by only looking
856 /// at the call event and the current state of analysis.
857 CallInlinePolicy mayInlineCallKind(const CallEvent &Call,
858 const ExplodedNode *Pred,
859 AnalyzerOptions &Opts,
860 const EvalCallOptions &CallOpts);
861
862 /// See if the given AnalysisDeclContext is built for a function that we
863 /// should always inline simply because it's small enough.
864 /// Apart from "small" functions, we also have "large" functions
865 /// (cf. isLarge()), some of which are huge (cf. isHuge()), and we classify
866 /// the remaining functions as "medium".
867 bool isSmall(AnalysisDeclContext *ADC) const;
868
869 /// See if the given AnalysisDeclContext is built for a function that we
870 /// should inline carefully because it looks pretty large.
871 bool isLarge(AnalysisDeclContext *ADC) const;
872
873 /// See if the given AnalysisDeclContext is built for a function that we
874 /// should never inline because it's legit gigantic.
875 bool isHuge(AnalysisDeclContext *ADC) const;
876
877 /// See if the given AnalysisDeclContext is built for a function that we
878 /// should inline, just by looking at the declaration of the function.
879 bool mayInlineDecl(AnalysisDeclContext *ADC) const;
880
881 /// Checks our policies and decides whether the given call should be inlined.
882 bool shouldInlineCall(const CallEvent &Call, const Decl *D,
883 const ExplodedNode *Pred,
884 const EvalCallOptions &CallOpts = {});
885
886 /// Checks whether our policies allow us to inline a non-POD type array
887 /// construction.
888 bool shouldInlineArrayConstruction(const ProgramStateRef State,
889 const CXXConstructExpr *CE,
890 const LocationContext *LCtx);
891
892 /// Checks whether our policies allow us to inline a non-POD type array
893 /// destruction.
894 /// \param Size The size of the array.
895 bool shouldInlineArrayDestruction(uint64_t Size);
896
897 /// Prepares the program state for array destruction. If no error happens
898 /// the function binds a 'PendingArrayDestruction' entry to the state, which
899 /// it returns along with the index. If any error happens (we fail to read
900 /// the size, the index would be -1, etc.) the function will return the
901 /// original state along with an index of 0. The actual element count of the
902 /// array can be accessed by the optional 'ElementCountVal' parameter. \param
903 /// State The program state. \param Region The memory region where the array
904 /// is stored. \param ElementTy The type an element in the array. \param LCty
905 /// The location context. \param ElementCountVal A pointer to an optional
906 /// SVal. If specified, the size of the array will be returned in it. It can
907 /// be Unknown.
908 std::pair<ProgramStateRef, uint64_t> prepareStateForArrayDestruction(
909 const ProgramStateRef State, const MemRegion *Region,
910 const QualType &ElementTy, const LocationContext *LCtx,
911 SVal *ElementCountVal = nullptr);
912
913 /// Checks whether we construct an array of non-POD type, and decides if the
914 /// constructor should be inkoved once again.
915 bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
916 const LocationContext *LCtx);
917
918 void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
919 NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
920
921 void ctuBifurcate(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
922 ExplodedNode *Pred, ProgramStateRef State);
923
924 /// Returns true if the CTU analysis is running its second phase.
925 bool isSecondPhaseCTU() { return IsCTUEnabled && !Engine.getCTUWorkList(); }
926
927 /// Conservatively evaluate call by invalidating regions and binding
928 /// a conjured return value.
929 void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
930 ExplodedNode *Pred, ProgramStateRef State);
931
932 /// Either inline or process the call conservatively (or both), based
933 /// on DynamicDispatchBifurcation data.
934 void BifurcateCall(const MemRegion *BifurReg,
935 const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
936 ExplodedNode *Pred);
937
938 bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
939
940 /// Models a trivial copy or move constructor or trivial assignment operator
941 /// call with a simple bind.
942 void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
943 const CallEvent &Call);
944
945 /// If the value of the given expression \p InitWithAdjustments is a NonLoc,
946 /// copy it into a new temporary object region, and replace the value of the
947 /// expression with that.
948 ///
949 /// If \p Result is provided, the new region will be bound to this expression
950 /// instead of \p InitWithAdjustments.
951 ///
952 /// Returns the temporary region with adjustments into the optional
953 /// OutRegionWithAdjustments out-parameter if a new region was indeed needed,
954 /// otherwise sets it to nullptr.
955 ProgramStateRef createTemporaryRegionIfNeeded(
956 ProgramStateRef State, const LocationContext *LC,
957 const Expr *InitWithAdjustments, const Expr *Result = nullptr,
958 const SubRegion **OutRegionWithAdjustments = nullptr);
959
960 /// Returns a region representing the `Idx`th element of a (possibly
961 /// multi-dimensional) array, for the purposes of element construction or
962 /// destruction.
963 ///
964 /// On return, \p Ty will be set to the base type of the array.
965 ///
966 /// If the type is not an array type at all, the original value is returned.
967 /// Otherwise the "IsArray" flag is set.
968 static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
969 QualType &Ty, bool &IsArray, unsigned Idx = 0);
970
971 /// Common code that handles either a CXXConstructExpr or a
972 /// CXXInheritedCtorInitExpr.
973 void handleConstructor(const Expr *E, ExplodedNode *Pred,
974 ExplodedNodeSet &Dst);
975
976public:
977 /// Note whether this loop has any more iterations to model. These methods
978 // are essentially an interface for a GDM trait. Further reading in
979 /// ExprEngine::VisitObjCForCollectionStmt().
980 [[nodiscard]] static ProgramStateRef
982 const ObjCForCollectionStmt *O,
983 const LocationContext *LC, bool HasMoreIteraton);
984
985 [[nodiscard]] static ProgramStateRef
986 removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O,
987 const LocationContext *LC);
988
989 [[nodiscard]] static bool hasMoreIteration(ProgramStateRef State,
990 const ObjCForCollectionStmt *O,
991 const LocationContext *LC);
992
993private:
994 /// Assuming we construct an array of non-POD types, this method allows us
995 /// to store which element is to be constructed next.
996 static ProgramStateRef
997 setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
998 const LocationContext *LCtx, unsigned Idx);
999
1000 static ProgramStateRef
1001 removeIndexOfElementToConstruct(ProgramStateRef State,
1002 const CXXConstructExpr *E,
1003 const LocationContext *LCtx);
1004
1005 /// Assuming we destruct an array of non-POD types, this method allows us
1006 /// to store which element is to be destructed next.
1007 static ProgramStateRef setPendingArrayDestruction(ProgramStateRef State,
1008 const LocationContext *LCtx,
1009 unsigned Idx);
1010
1011 static ProgramStateRef
1012 removePendingArrayDestruction(ProgramStateRef State,
1013 const LocationContext *LCtx);
1014
1015 /// Sets the size of the array in a pending ArrayInitLoopExpr.
1016 static ProgramStateRef setPendingInitLoop(ProgramStateRef State,
1017 const CXXConstructExpr *E,
1018 const LocationContext *LCtx,
1019 unsigned Idx);
1020
1021 static ProgramStateRef removePendingInitLoop(ProgramStateRef State,
1022 const CXXConstructExpr *E,
1023 const LocationContext *LCtx);
1024
1025 static ProgramStateRef
1026 removeStateTraitsUsedForArrayEvaluation(ProgramStateRef State,
1027 const CXXConstructExpr *E,
1028 const LocationContext *LCtx);
1029
1030 /// Store the location of a C++ object corresponding to a statement
1031 /// until the statement is actually encountered. For example, if a DeclStmt
1032 /// has CXXConstructExpr as its initializer, the object would be considered
1033 /// to be "under construction" between CXXConstructExpr and DeclStmt.
1034 /// This allows, among other things, to keep bindings to variable's fields
1035 /// made within the constructor alive until its declaration actually
1036 /// goes into scope.
1037 static ProgramStateRef
1038 addObjectUnderConstruction(ProgramStateRef State,
1039 const ConstructionContextItem &Item,
1040 const LocationContext *LC, SVal V);
1041
1042 /// Mark the object as fully constructed, cleaning up the state trait
1043 /// that tracks objects under construction.
1044 static ProgramStateRef
1045 finishObjectConstruction(ProgramStateRef State,
1046 const ConstructionContextItem &Item,
1047 const LocationContext *LC);
1048
1049 /// If the given expression corresponds to a temporary that was used for
1050 /// passing into an elidable copy/move constructor and that constructor
1051 /// was actually elided, track that we also need to elide the destructor.
1052 static ProgramStateRef elideDestructor(ProgramStateRef State,
1053 const CXXBindTemporaryExpr *BTE,
1054 const LocationContext *LC);
1055
1056 /// Stop tracking the destructor that corresponds to an elided constructor.
1057 static ProgramStateRef
1058 cleanupElidedDestructor(ProgramStateRef State,
1059 const CXXBindTemporaryExpr *BTE,
1060 const LocationContext *LC);
1061
1062 /// Returns true if the given expression corresponds to a temporary that
1063 /// was constructed for passing into an elidable copy/move constructor
1064 /// and that constructor was actually elided.
1065 static bool isDestructorElided(ProgramStateRef State,
1066 const CXXBindTemporaryExpr *BTE,
1067 const LocationContext *LC);
1068
1069 /// Check if all objects under construction have been fully constructed
1070 /// for the given context range (including FromLC, not including ToLC).
1071 /// This is useful for assertions. Also checks if elided destructors
1072 /// were cleaned up.
1073 static bool areAllObjectsFullyConstructed(ProgramStateRef State,
1074 const LocationContext *FromLC,
1075 const LocationContext *ToLC);
1076};
1077
1078/// Traits for storing the call processing policy inside GDM.
1079/// The GDM stores the corresponding CallExpr pointer.
1080// FIXME: This does not use the nice trait macros because it must be accessible
1081// from multiple translation units.
1083template <>
1085 public ProgramStatePartialTrait<const void*> {
1086 static void *GDMIndex();
1087};
1088
1089} // namespace ento
1090
1091} // namespace clang
1092
1093#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
#define V(N, I)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Stores options for the analyzer from the command line.
Represents a loop initializing the elements of an array.
Definition Expr.h:5971
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2724
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6927
Represents an attribute applied to a statement.
Definition Stmt.h:2204
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
BinaryOperatorKind Opcode
Definition Expr.h:4046
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6671
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Definition CFG.h:445
Represents C++ object destructor implicitly generated for base object in destructor.
Definition CFG.h:496
Represents a single basic block in a source-level CFG.
Definition CFG.h:632
Represents C++ object destructor generated from a call to delete.
Definition CFG.h:470
Represents a top-level expression in a basic block.
Definition CFG.h:55
Represents C++ object destructor implicitly generated by compiler on various occasions.
Definition CFG.h:394
Represents C++ base or member initializer from constructor's initialization list.
Definition CFG.h:229
Represents C++ object destructor implicitly generated for member object in destructor.
Definition CFG.h:517
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
Definition CFG.h:538
Represents binding an expression to a temporary.
Definition ExprCXX.h:1494
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
Represents a call to a C++ constructor.
Definition ExprCXX.h:1549
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2627
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1752
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2356
Represents the this expression in C++.
Definition ExprCXX.h:1155
Represents a point when we begin processing an inlined call.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3679
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3608
Represents a single point (AST node) in the program that requires attention during construction of an...
ConstructionContext's subclasses describe different ways of constructing an object in C++.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1632
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:112
This represents a GCC inline-assembly statement extension.
Definition Stmt.h:3447
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1969
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const StackFrameContext * getStackFrame() const
virtual bool inTopFrame() const
This represents a Microsoft inline-assembly statement extension.
Definition Stmt.h:3666
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4921
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3367
This represents a decl that may have a name.
Definition Decl.h:274
Represents Objective-C's @synchronized statement.
Definition StmtObjC.h:303
Represents Objective-C's collection statement.
Definition StmtObjC.h:23
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:580
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2530
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
A (possibly-)qualified type.
Definition TypeBase.h:937
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3161
Stmt - This represents one statement.
Definition Stmt.h:86
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2510
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
This class is used for tools that requires cross translation unit capability.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Represents an abstract call to a function or method along a particular path.
Definition CallEvent.h:153
CoreEngine - Implements the core logic of the graph-reachability analysis.
Definition CoreEngine.h:50
WorkList * getCTUWorkList() const
Definition CoreEngine.h:162
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
ProgramStateManager & getStateManager()
Definition ExprEngine.h:480
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx)
processCFGElement - Called by CoreEngine.
void processBranch(const Stmt *Condition, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF, std::optional< unsigned > IterationsCompletedInLoop)
ProcessBranch - Called by CoreEngine.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void runCheckersForBlockEntrance(const BlockEntrance &Entrance, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
BasicValueFactory & getBasicVals()
Definition ExprEngine.h:496
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.
Definition ExprEngine.h:819
void processEndOfFunction(ExplodedNode *Pred, const ReturnStmt *RS=nullptr)
Called by CoreEngine.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void removeDeadOnEndOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBifurcation - Given the nodes in 'Src', eagerly assume concrete boolean values for '...
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
const CoreEngine & getCoreEngine() const
Definition ExprEngine.h:511
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
Definition ExprEngine.h:684
void processCallEnter(CallEnter CE, ExplodedNode *Pred)
Generate the entry node of the callee.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
Definition ExprEngine.h:469
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
static bool hasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC)
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
void processCallExit(ExplodedNode *Pred)
Generate the sequence of nodes that simulate the call exit and the post visit for CallExpr.
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
void processStaticInitializer(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
const SymbolManager & getSymbolManager() const
Definition ExprEngine.h:501
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
Definition ExprEngine.h:770
unsigned getNumVisited(const LocationContext *LC, const CFGBlock *Block) const
Definition ExprEngine.h:296
std::string DumpGraph(bool trim=false, StringRef Filename="")
Dump graph to the specified filename.
bool hasWorkRemaining() const
Definition ExprEngine.h:509
void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
virtual ~ExprEngine()=default
InliningModes
The modes of inlining, which override the default analysis-wide settings.
Definition ExprEngine.h:126
@ Inline_Minimal
Do minimal inlining of callees.
Definition ExprEngine.h:131
@ Inline_Regular
Follow the default settings for inlining callees.
Definition ExprEngine.h:128
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, ArrayRef< std::pair< SVal, SVal > > LocAndVals, const LocationContext *LCtx, PointerEscapeKind Kind, const CallEvent *Call)
Call PointerEscape callback when a value escapes as a result of bind.
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, unsigned NumVisitedCaller, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
Find location of the object that is being constructed by a given constructor.
const LocationContext * getRootLocationContext() const
Definition ExprEngine.h:270
static ProgramStateRef removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC)
const ExplodedGraph & getGraph() const
Definition ExprEngine.h:329
const StoreManager & getStoreManager() const
Definition ExprEngine.h:484
void setCurrLocationContextAndBlock(const LocationContext *LC, const CFGBlock *B)
Definition ExprEngine.h:245
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption)
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
AnalysisDeclContextManager & getAnalysisDeclContextManager()
Definition ExprEngine.h:220
const ProgramStateManager & getStateManager() const
Definition ExprEngine.h:481
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives which element is being constructed in a non-POD type array.
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static std::pair< const ProgramPointTag *, const ProgramPointTag * > getEagerlyAssumeBifurcationTags()
void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Handle ++ and – (both pre- and post-increment).
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition ExprEngine.h:215
StoreManager & getStoreManager()
Definition ExprEngine.h:483
const ConstraintManager & getConstraintManager() const
Definition ExprEngine.h:491
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call)
Evaluate a call, running pre- and post-call checkers and allowing checkers to be responsible for hand...
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
BugReporter & getBugReporter()
Definition ExprEngine.h:231
bool hasEmptyWorkList() const
Definition ExprEngine.h:508
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
ConstCFGElementRef getCFGElementRef() const
Definition ExprEngine.h:292
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const LocationContext *LCtx)
Retreives which element is being destructed in a non-POD type array.
ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const LocationContext *LCtx, QualType T, QualType ExTy, const CastExpr *CastE, NodeBuilder &Bldr, ExplodedNode *Pred)
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
static const ProgramPointTag * cleanupNodeTag()
A tag to track convenience transitions, which can be removed at cleanup.
void ConstructInitList(const Expr *Source, ArrayRef< Expr * > Args, bool IsTransparent, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
cross_tu::CrossTranslationUnitContext * getCrossTranslationUnitContext()
Definition ExprEngine.h:235
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
void processEndWorklist()
Called by CoreEngine when the analysis worklist has terminated.
void resetCurrLocationContextAndBlock()
Definition ExprEngine.h:260
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:224
SymbolManager & getSymbolManager()
Definition ExprEngine.h:500
void processBeginOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
bool wasBlocksExhausted() const
Definition ExprEngine.h:507
MemRegionManager & getRegionManager()
Definition ExprEngine.h:502
const AnalysisManager & getAnalysisManager() const
Definition ExprEngine.h:218
ProgramStateRef bindReturnValue(const CallEvent &Call, const LocationContext *LCtx, ProgramStateRef State)
Create a new state in which the call return value is binded to the call origin expression.
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
void processSwitch(const SwitchStmt *Switch, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProcessSwitch - Called by CoreEngine.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const
ConstraintManager & getConstraintManager()
Definition ExprEngine.h:488
DataTag::Factory & getDataTags()
Definition ExprEngine.h:504
const NodeBuilderContext & getBuilderContext() const
Definition ExprEngine.h:265
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getNumVisitedCurrent() const
Definition ExprEngine.h:302
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
AnalysisManager & getAnalysisManager()
Definition ExprEngine.h:217
ExplodedGraph & getGraph()
Definition ExprEngine.h:328
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
const BugReporter & getBugReporter() const
Definition ExprEngine.h:232
const LocationContext * getCurrLocationContext() const
Get the 'current' location context corresponding to the current work item (elementary analysis step h...
Definition ExprEngine.h:282
void handleUOExtension(ExplodedNode *N, const UnaryOperator *U, NodeBuilder &Bldr)
SValBuilder & getSValBuilder()
Definition ExprEngine.h:228
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArrayInitLoopExpr - Transfer function for array init loop.
ProgramStateRef updateObjectsUnderConstruction(SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx, const ConstructionContext *CC, const EvalCallOptions &CallOpts)
Update the program state with all the path-sensitive information that's necessary to perform construc...
bool ExecuteWorkList(const LocationContext *L, unsigned Steps=150000)
Returns true if there is still simulation state on the worklist.
Definition ExprEngine.h:208
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
void processCFGBlockEntrance(const BlockEdge &L, const BlockEntrance &BE, NodeBuilder &Builder, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
const CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
Definition ExprEngine.h:288
static ProgramStateRef setWhetherHasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC, bool HasMoreIteraton)
Note whether this loop has any more iterations to model. These methods.
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
const SValBuilder & getSValBuilder() const
Definition ExprEngine.h:229
void processIndirectGoto(ExplodedNodeSet &Dst, const Expr *Tgt, const CFGBlock *Dispatch, ExplodedNode *Pred)
processIndirectGoto - Called by CoreEngine.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:98
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition CoreEngine.h:217
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:244
GRBugReporter is used for generating path-sensitive reports.
ProgramState - This class encapsulates:
Information about invalidation for a particular region/symbol.
Definition MemRegion.h:1657
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:56
Definition ARM.cpp:1102
Definition SPIR.cpp:35
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
llvm::DenseSet< const Decl * > SetOfConstDecls
llvm::DenseSet< SymbolRef > InvalidatedSymbols
Definition Store.h:51
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
CFGBlock::ConstCFGElementRef ConstCFGElementRef
Definition CFG.h:1227
@ Result
The result type of a method or function.
Definition TypeBase.h:905
Hints for figuring out of a call should be inlined during evalCall().
Definition ExprEngine.h:94
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
Definition ExprEngine.h:109
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition ExprEngine.h:104
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Definition ExprEngine.h:101
bool IsElidableCtorThatHasNotBeenElided
This call is a pre-C++17 elidable constructor that we failed to elide because we failed to compute th...
Definition ExprEngine.h:116
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition ExprEngine.h:97
Traits for storing the call processing policy inside GDM.