|
|
|||
File indexing completed on 2026-05-10 08:36:25
0001 //===- TypeErasedDataflowAnalysis.h -----------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines type-erased base types and functions for building dataflow 0010 // analyses that run over Control-Flow Graphs (CFGs). 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H 0015 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H 0016 0017 #include <optional> 0018 #include <utility> 0019 #include <vector> 0020 0021 #include "clang/AST/ASTContext.h" 0022 #include "clang/AST/Stmt.h" 0023 #include "clang/Analysis/CFG.h" 0024 #include "clang/Analysis/FlowSensitive/AdornedCFG.h" 0025 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" 0026 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" 0027 #include "clang/Analysis/FlowSensitive/DataflowLattice.h" 0028 #include "llvm/ADT/Any.h" 0029 #include "llvm/Support/Error.h" 0030 0031 namespace clang { 0032 namespace dataflow { 0033 0034 struct DataflowAnalysisOptions { 0035 /// Options for the built-in model, or empty to not apply them. 0036 // FIXME: Remove this option once the framework supports composing analyses 0037 // (at which point the built-in transfer functions can be simply a standalone 0038 // analysis). 0039 std::optional<DataflowAnalysisContext::Options> BuiltinOpts = 0040 DataflowAnalysisContext::Options{}; 0041 }; 0042 0043 /// Type-erased lattice element container. 0044 /// 0045 /// Requirements: 0046 /// 0047 /// The type of the object stored in the container must be a bounded 0048 /// join-semilattice. 0049 struct TypeErasedLattice { 0050 llvm::Any Value; 0051 }; 0052 0053 /// Type-erased base class for dataflow analyses built on a single lattice type. 0054 class TypeErasedDataflowAnalysis : public Environment::ValueModel { 0055 DataflowAnalysisOptions Options; 0056 0057 public: 0058 TypeErasedDataflowAnalysis() : Options({}) {} 0059 0060 TypeErasedDataflowAnalysis(DataflowAnalysisOptions Options) 0061 : Options(Options) {} 0062 0063 virtual ~TypeErasedDataflowAnalysis() {} 0064 0065 /// Returns the `ASTContext` that is used by the analysis. 0066 virtual ASTContext &getASTContext() = 0; 0067 0068 /// Returns a type-erased lattice element that models the initial state of a 0069 /// basic block. 0070 virtual TypeErasedLattice typeErasedInitialElement() = 0; 0071 0072 /// Joins two type-erased lattice elements by computing their least upper 0073 /// bound. Places the join result in the left element and returns an effect 0074 /// indicating whether any changes were made to it. 0075 virtual TypeErasedLattice joinTypeErased(const TypeErasedLattice &, 0076 const TypeErasedLattice &) = 0; 0077 0078 /// Chooses a lattice element that approximates the current element at a 0079 /// program point, given the previous element at that point. Places the 0080 /// widened result in the current element (`Current`). Widening is optional -- 0081 /// it is only needed to either accelerate convergence (for lattices with 0082 /// non-trivial height) or guarantee convergence (for lattices with infinite 0083 /// height). 0084 /// 0085 /// Returns an indication of whether any changes were made to `Current` in 0086 /// order to widen. This saves a separate call to `isEqualTypeErased` after 0087 /// the widening. 0088 virtual LatticeJoinEffect 0089 widenTypeErased(TypeErasedLattice &Current, 0090 const TypeErasedLattice &Previous) = 0; 0091 0092 /// Returns true if and only if the two given type-erased lattice elements are 0093 /// equal. 0094 virtual bool isEqualTypeErased(const TypeErasedLattice &, 0095 const TypeErasedLattice &) = 0; 0096 0097 /// Applies the analysis transfer function for a given control flow graph 0098 /// element and type-erased lattice element. 0099 virtual void transferTypeErased(const CFGElement &, TypeErasedLattice &, 0100 Environment &) = 0; 0101 0102 /// Applies the analysis transfer function for a given edge from a CFG block 0103 /// of a conditional statement. 0104 /// @param Stmt The condition which is responsible for the split in the CFG. 0105 /// @param Branch True if the edge goes to the basic block where the 0106 /// condition is true. 0107 // FIXME: Change `Stmt` argument to a reference. 0108 virtual void transferBranchTypeErased(bool Branch, const Stmt *, 0109 TypeErasedLattice &, Environment &) = 0; 0110 0111 /// If the built-in model is enabled, returns the options to be passed to 0112 /// them. Otherwise returns empty. 0113 const std::optional<DataflowAnalysisContext::Options> & 0114 builtinOptions() const { 0115 return Options.BuiltinOpts; 0116 } 0117 }; 0118 0119 /// Type-erased model of the program at a given program point. 0120 struct TypeErasedDataflowAnalysisState { 0121 /// Type-erased model of a program property. 0122 TypeErasedLattice Lattice; 0123 0124 /// Model of the state of the program (store and heap). 0125 Environment Env; 0126 0127 TypeErasedDataflowAnalysisState(TypeErasedLattice Lattice, Environment Env) 0128 : Lattice(std::move(Lattice)), Env(std::move(Env)) {} 0129 0130 TypeErasedDataflowAnalysisState fork() const { 0131 return TypeErasedDataflowAnalysisState(Lattice, Env.fork()); 0132 } 0133 }; 0134 0135 /// A callback to be called with the state before or after visiting a CFG 0136 /// element. 0137 using CFGEltCallbackTypeErased = std::function<void( 0138 const CFGElement &, const TypeErasedDataflowAnalysisState &)>; 0139 0140 /// A pair of callbacks to be called with the state before and after visiting a 0141 /// CFG element. 0142 /// Either or both of the callbacks may be null. 0143 struct CFGEltCallbacksTypeErased { 0144 CFGEltCallbackTypeErased Before; 0145 CFGEltCallbackTypeErased After; 0146 }; 0147 0148 /// Performs dataflow analysis and returns a mapping from basic block IDs to 0149 /// dataflow analysis states that model the respective basic blocks. Indices of 0150 /// the returned vector correspond to basic block IDs. Returns an error if the 0151 /// dataflow analysis cannot be performed successfully. Otherwise, calls 0152 /// `PostAnalysisCallbacks` on each CFG element with the final analysis results 0153 /// before and after that program point. 0154 /// 0155 /// `MaxBlockVisits` caps the number of block visits during analysis. It doesn't 0156 /// distinguish between repeat visits to the same block and visits to distinct 0157 /// blocks. This parameter is a backstop to prevent infinite loops, in the case 0158 /// of bugs in the lattice and/or transfer functions that prevent the analysis 0159 /// from converging. 0160 llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>> 0161 runTypeErasedDataflowAnalysis( 0162 const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, 0163 const Environment &InitEnv, 0164 const CFGEltCallbacksTypeErased &PostAnalysisCallbacks, 0165 std::int32_t MaxBlockVisits); 0166 0167 } // namespace dataflow 0168 } // namespace clang 0169 0170 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|