aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-05-08 08:36:53 +0200
committerGitHub <noreply@github.com>2024-05-08 08:36:53 +0200
commit23ae482bd01d7c966f871ddd620e9a26d6d66299 (patch)
tree32f510cac243425cdaeb9efd3f838985ec6ecedd
parent8755d24cb34b902557469445e1983850e0ce7cc7 (diff)
downloadllvm-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.
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h5
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h24
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp10
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.