aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2023-06-15 15:56:25 +0200
committerSam McCall <sam.mccall@gmail.com>2023-07-04 12:19:44 +0200
commit2fd614efc1bb9c27f1bc6c3096c60a7fe121e274 (patch)
tree29f416b79e98f32164e9e710cce6910eb951d678 /clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
parent61bcaae7ab04e99bf3cd632c321959f7b91d193c (diff)
downloadllvm-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.cpp23
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 *