diff options
author | Sam McCall <sam.mccall@gmail.com> | 2023-06-15 15:56:25 +0200 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2023-07-04 12:19:44 +0200 |
commit | 2fd614efc1bb9c27f1bc6c3096c60a7fe121e274 (patch) | |
tree | 29f416b79e98f32164e9e710cce6910eb951d678 /clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp | |
parent | 61bcaae7ab04e99bf3cd632c321959f7b91d193c (diff) | |
download | llvm-2fd614efc1bb9c27f1bc6c3096c60a7fe121e274.zip llvm-2fd614efc1bb9c27f1bc6c3096c60a7fe121e274.tar.gz llvm-2fd614efc1bb9c27f1bc6c3096c60a7fe121e274.tar.bz2 |
[dataflow] Add dedicated representation of boolean formulas
This is the first step in untangling the two current jobs of BoolValue.
=== Desired end-state: ===
- BoolValue will model C++ booleans e.g. held in StorageLocations.
this includes describing uncertainty (e.g. "top" is a Value concern)
- Formula describes analysis-level assertions in terms of SAT atoms.
These can still be linked together: a BoolValue may have a corresponding
SAT atom which is constrained by formulas.
=== Done in this patch: ===
BoolValue is left intact, Formula is just the input type to the
SAT solver, and we build formulas as needed to invoke the solver.
=== Incidental changes to debug string printing: ===
- variables renamed from B0 etc to V0 etc
B0 collides with the names of basic blocks, which is confusing when
debugging flow conditions.
- debug printing of formulas (Formula and Atom) uses operator<<
rather than debugString(), so works with gtest.
Therefore moved out of DebugSupport.h
- Did the same to Solver::Result, and some helper changes to SolverTest,
so that we get useful messages on unit test failures
- formulas are now printed as infix expressions on one line, rather than
wrapped/indented S-exprs. My experience is that this is easier to scan
FCs for small examples, and large ones are unreadable either way.
- most of the several debugString() functions for constraints/results
are unused, so removed them rather than updating tests.
Inlined the one that was actually used into its callsite.
Differential Revision: https://reviews.llvm.org/D153366
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp')
-rw-r--r-- | clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index 37bcc8b..42cc6d4 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -15,6 +15,7 @@ #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/AST/ExprCXX.h" #include "clang/Analysis/FlowSensitive/DebugSupport.h" +#include "clang/Analysis/FlowSensitive/Formula.h" #include "clang/Analysis/FlowSensitive/Logger.h" #include "clang/Analysis/FlowSensitive/Value.h" #include "llvm/ADT/SetOperations.h" @@ -23,9 +24,12 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <memory> +#include <string> #include <utility> +#include <vector> static llvm::cl::opt<std::string> DataflowLog( "dataflow-log", llvm::cl::Hidden, llvm::cl::ValueOptional, @@ -129,7 +133,10 @@ Solver::Result DataflowAnalysisContext::querySolver(llvm::SetVector<BoolValue *> Constraints) { Constraints.insert(&arena().makeLiteral(true)); Constraints.insert(&arena().makeNot(arena().makeLiteral(false))); - return S->solve(Constraints.getArrayRef()); + std::vector<const Formula *> Formulas; + for (const BoolValue *Constraint : Constraints) + Formulas.push_back(&arena().getFormula(*Constraint)); + return S->solve(Formulas); } bool DataflowAnalysisContext::flowConditionImplies(AtomicBoolValue &Token, @@ -191,15 +198,21 @@ void DataflowAnalysisContext::addTransitiveFlowConditionConstraints( void DataflowAnalysisContext::dumpFlowCondition(AtomicBoolValue &Token, llvm::raw_ostream &OS) { + // TODO: accumulate formulas directly instead llvm::SetVector<BoolValue *> Constraints; Constraints.insert(&Token); llvm::DenseSet<AtomicBoolValue *> VisitedTokens; addTransitiveFlowConditionConstraints(Token, Constraints, VisitedTokens); - llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames = { - {&arena().makeLiteral(false), "False"}, - {&arena().makeLiteral(true), "True"}}; - OS << debugString(Constraints.getArrayRef(), AtomNames); + // TODO: have formulas know about true/false directly instead + Atom True = arena().getFormula(arena().makeLiteral(true)).getAtom(); + Atom False = arena().getFormula(arena().makeLiteral(false)).getAtom(); + Formula::AtomNames Names = {{False, "false"}, {True, "true"}}; + + for (const auto *Constraint : Constraints) { + arena().getFormula(*Constraint).print(OS, &Names); + OS << "\n"; + } } const ControlFlowContext * |