1//== SubEngine.h - Interface of the subengine of CoreEngine --------*- 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 the interface of a subengine of the CoreEngine.
10//
11//===----------------------------------------------------------------------===//
12#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
13#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
14
15#include "clang/Analysis/ProgramPoint.h"
16#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
17#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
18#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19
20namespace clang {
21
22class CFGBlock;
23class CFGElement;
24class LocationContext;
25class Stmt;
26
27namespace cross_tu {
28class CrossTranslationUnitContext;
29}
30
31namespace ento {
32
33struct NodeBuilderContext;
34class AnalysisManager;
35class ExplodedNodeSet;
36class ExplodedNode;
37class ProgramState;
38class ProgramStateManager;
39class BlockCounter;
40class BranchNodeBuilder;
41class IndirectGotoNodeBuilder;
42class SwitchNodeBuilder;
43class EndOfFunctionNodeBuilder;
44class NodeBuilderWithSinks;
45class MemRegion;
46
47class SubEngine {
48  virtual void anchor();
49public:
50  virtual ~SubEngine() {}
51
52  virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
53
54  virtual AnalysisManager &getAnalysisManager() = 0;
55
56  virtual cross_tu::CrossTranslationUnitContext *
57  getCrossTranslationUnitContext() = 0;
58
59  virtual ProgramStateManager &getStateManager() = 0;
60
61  /// Called by CoreEngine. Used to generate new successor
62  /// nodes by processing the 'effects' of a block-level statement.
63  virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
64                                 unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
65
66  /// Called by CoreEngine when it starts processing a CFGBlock.  The
67  /// SubEngine is expected to populate dstNodes with new nodes representing
68  /// updated analysis state, or generate no nodes at all if it doesn't.
69  virtual void processCFGBlockEntrance(const BlockEdge &L,
70                                       NodeBuilderWithSinks &nodeBuilder,
71                                       ExplodedNode *Pred) = 0;
72
73  /// Called by CoreEngine.  Used to generate successor
74  ///  nodes by processing the 'effects' of a branch condition.
75  virtual void processBranch(const Stmt *Condition,
76                             NodeBuilderContext& BuilderCtx,
77                             ExplodedNode *Pred,
78                             ExplodedNodeSet &Dst,
79                             const CFGBlock *DstT,
80                             const CFGBlock *DstF) = 0;
81
82  /// Called by CoreEngine.
83  /// Used to generate successor nodes for temporary destructors depending
84  /// on whether the corresponding constructor was visited.
85  virtual void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
86                                             NodeBuilderContext &BldCtx,
87                                             ExplodedNode *Pred,
88                                             ExplodedNodeSet &Dst,
89                                             const CFGBlock *DstT,
90                                             const CFGBlock *DstF) = 0;
91
92  /// Called by CoreEngine.  Used to processing branching behavior
93  /// at static initializers.
94  virtual void processStaticInitializer(const DeclStmt *DS,
95                                        NodeBuilderContext& BuilderCtx,
96                                        ExplodedNode *Pred,
97                                        ExplodedNodeSet &Dst,
98                                        const CFGBlock *DstT,
99                                        const CFGBlock *DstF) = 0;
100
101  /// Called by CoreEngine.  Used to generate successor
102  /// nodes by processing the 'effects' of a computed goto jump.
103  virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
104
105  /// Called by CoreEngine.  Used to generate successor
106  /// nodes by processing the 'effects' of a switch statement.
107  virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
108
109  /// Called by CoreEngine.  Used to notify checkers that processing a
110  /// function has begun. Called for both inlined and and top-level functions.
111  virtual void processBeginOfFunction(NodeBuilderContext &BC,
112                                      ExplodedNode *Pred,
113                                      ExplodedNodeSet &Dst,
114                                      const BlockEdge &L) = 0;
115
116  /// Called by CoreEngine.  Used to notify checkers that processing a
117  /// function has ended. Called for both inlined and and top-level functions.
118  virtual void processEndOfFunction(NodeBuilderContext& BC,
119                                    ExplodedNode *Pred,
120                                    const ReturnStmt *RS = nullptr) = 0;
121
122  // Generate the entry node of the callee.
123  virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
124                                ExplodedNode *Pred) = 0;
125
126  // Generate the first post callsite node.
127  virtual void processCallExit(ExplodedNode *Pred) = 0;
128
129  /// Called by ConstraintManager. Used to call checker-specific
130  /// logic for handling assumptions on symbolic values.
131  virtual ProgramStateRef processAssume(ProgramStateRef state,
132                                       SVal cond, bool assumption) = 0;
133
134  /// processRegionChanges - Called by ProgramStateManager whenever a change is
135  /// made to the store. Used to update checkers that track region values.
136  virtual ProgramStateRef
137  processRegionChanges(ProgramStateRef state,
138                       const InvalidatedSymbols *invalidated,
139                       ArrayRef<const MemRegion *> ExplicitRegions,
140                       ArrayRef<const MemRegion *> Regions,
141                       const LocationContext *LCtx,
142                       const CallEvent *Call) = 0;
143
144
145  inline ProgramStateRef
146  processRegionChange(ProgramStateRef state,
147                      const MemRegion* MR,
148                      const LocationContext *LCtx) {
149    return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
150  }
151
152  virtual ProgramStateRef processPointerEscapedOnBind(
153      ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals,
154      const LocationContext *LCtx, PointerEscapeKind Kind,
155      const CallEvent *Call) = 0;
156
157  virtual ProgramStateRef
158  notifyCheckersOfPointerEscape(ProgramStateRef State,
159                           const InvalidatedSymbols *Invalidated,
160                           ArrayRef<const MemRegion *> ExplicitRegions,
161                           const CallEvent *Call,
162                           RegionAndSymbolInvalidationTraits &HTraits) = 0;
163
164  /// printJson - Called by ProgramStateManager to print checker-specific data.
165  virtual void printJson(raw_ostream &Out, ProgramStateRef State,
166                         const LocationContext *LCtx, const char *NL,
167                         unsigned int Space, bool IsDot) const = 0;
168
169  /// Called by CoreEngine when the analysis worklist is either empty or the
170  //  maximum number of analysis steps have been reached.
171  virtual void processEndWorklist() = 0;
172};
173
174} // end GR namespace
175
176} // end clang namespace
177
178#endif
179