diff options
author | martinboehme <mboehme@google.com> | 2024-05-08 08:36:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-08 08:36:53 +0200 |
commit | 23ae482bd01d7c966f871ddd620e9a26d6d66299 (patch) | |
tree | 32f510cac243425cdaeb9efd3f838985ec6ecedd | |
parent | 8755d24cb34b902557469445e1983850e0ce7cc7 (diff) | |
download | llvm-23ae482bd01d7c966f871ddd620e9a26d6d66299.zip llvm-23ae482bd01d7c966f871ddd620e9a26d6d66299.tar.gz llvm-23ae482bd01d7c966f871ddd620e9a26d6d66299.tar.bz2 |
[clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (#91316)
For some callers (see change in DataflowAnalysis.h), this is more
convenient.
3 files changed, 29 insertions, 10 deletions
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 67eccdd0..763af24 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -283,9 +283,8 @@ llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction( if (!Context) return Context.takeError(); - auto OwnedSolver = std::make_unique<WatchedLiteralsSolver>(MaxSATIterations); - const WatchedLiteralsSolver *Solver = OwnedSolver.get(); - DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver)); + auto Solver = std::make_unique<WatchedLiteralsSolver>(MaxSATIterations); + DataflowAnalysisContext AnalysisContext(*Solver); Environment Env(AnalysisContext, FuncDecl); AnalysisT Analysis = createAnalysis<AnalysisT>(ASTCtx, Env); llvm::SmallVector<Diagnostic> Diagnostics; diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index aa2c366..5be4a11 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -67,7 +67,19 @@ public: DataflowAnalysisContext(std::unique_ptr<Solver> S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, - /*Logger=*/nullptr}); + /*Logger=*/nullptr}) + : DataflowAnalysisContext(*S, std::move(S), Opts) {} + + /// Constructs a dataflow analysis context. + /// + /// Requirements: + /// + /// `S` must outlive the `DataflowAnalysisContext`. + DataflowAnalysisContext(Solver &S, Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt, + /*Logger=*/nullptr}) + : DataflowAnalysisContext(S, nullptr, Opts) {} + ~DataflowAnalysisContext(); /// Sets a callback that returns the names and types of the synthetic fields @@ -209,6 +221,13 @@ private: using DenseMapInfo::isEqual; }; + /// `S` is the solver to use. `OwnedSolver` may be: + /// * Null (in which case `S` is non-onwed and must outlive this object), or + /// * Non-null (in which case it must refer to `S`, and the + /// `DataflowAnalysisContext will take ownership of `OwnedSolver`). + DataflowAnalysisContext(Solver &S, std::unique_ptr<Solver> &&OwnedSolver, + Options Opts); + // Extends the set of modeled field declarations. void addModeledFields(const FieldSet &Fields); @@ -232,7 +251,8 @@ private: Solver::Result::Status::Unsatisfiable; } - std::unique_ptr<Solver> S; + Solver &S; + std::unique_ptr<Solver> OwnedSolver; std::unique_ptr<Arena> A; // Maps from program declarations and statements to storage locations that are diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index e94fd39..4b86daa 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -170,7 +170,7 @@ DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, Solver::Result DataflowAnalysisContext::querySolver( llvm::SetVector<const Formula *> Constraints) { - return S->solve(Constraints.getArrayRef()); + return S.solve(Constraints.getArrayRef()); } bool DataflowAnalysisContext::flowConditionImplies(Atom Token, @@ -338,10 +338,10 @@ static std::unique_ptr<Logger> makeLoggerFromCommandLine() { return Logger::html(std::move(StreamFactory)); } -DataflowAnalysisContext::DataflowAnalysisContext(std::unique_ptr<Solver> S, - Options Opts) - : S(std::move(S)), A(std::make_unique<Arena>()), Opts(Opts) { - assert(this->S != nullptr); +DataflowAnalysisContext::DataflowAnalysisContext( + Solver &S, std::unique_ptr<Solver> &&OwnedSolver, Options Opts) + : S(S), OwnedSolver(std::move(OwnedSolver)), A(std::make_unique<Arena>()), + Opts(Opts) { // If the -dataflow-log command-line flag was set, synthesize a logger. // This is ugly but provides a uniform method for ad-hoc debugging dataflow- // based tools. |