[clang] b5414b5 - [clang][dataflow] Add DataflowEnvironment::dump()
Dmitri Gribenko via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 22 16:31:59 PDT 2022
Author: Dmitri Gribenko
Date: 2022-07-23T01:31:53+02:00
New Revision: b5414b566a5aedd90e41f01dd2b7b632afc5d5b7
URL: https://github.com/llvm/llvm-project/commit/b5414b566a5aedd90e41f01dd2b7b632afc5d5b7
DIFF: https://github.com/llvm/llvm-project/commit/b5414b566a5aedd90e41f01dd2b7b632afc5d5b7.diff
LOG: [clang][dataflow] Add DataflowEnvironment::dump()
Start by dumping the flow condition.
Reviewed By: ymandel
Differential Revision: https://reviews.llvm.org/D130398
Added:
Modified:
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
clang/unittests/Analysis/FlowSensitive/DebugSupportTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index 358ace0430f62..abc3183e1b0b5 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -23,6 +23,7 @@
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <memory>
#include <type_traits>
@@ -251,6 +252,8 @@ class DataflowAnalysisContext {
/// `Val2` imposed by the flow condition.
bool equivalentBoolValues(BoolValue &Val1, BoolValue &Val2);
+ LLVM_DUMP_METHOD void dumpFlowCondition(AtomicBoolValue &Token);
+
private:
struct NullableQualTypeDenseMapInfo : private llvm::DenseMapInfo<QualType> {
static QualType getEmptyKey() {
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index ce195f0662f53..f17df36f6a4a3 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -19,7 +19,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
-#include "clang/AST/TypeOrdering.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
@@ -325,6 +324,8 @@ class Environment {
/// imply that `Val` is true.
bool flowConditionImplies(BoolValue &Val) const;
+ LLVM_DUMP_METHOD void dump() const;
+
private:
/// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
/// return null.
diff --git a/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h b/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
index 74367d29b2a0f..b8efdeb61d280 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
@@ -42,6 +42,20 @@ std::string debugString(
const BoolValue &B,
llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames = {{}});
+/// Returns a string representation for `Constraints` - a collection of boolean
+/// formulas.
+///
+/// Atomic booleans appearing in the boolean value `Constraints` are assigned to
+/// labels either specified in `AtomNames` or created by default rules as B0,
+/// B1, ...
+///
+/// Requirements:
+///
+/// Names assigned to atoms should not be repeated in `AtomNames`.
+std::string debugString(
+ const llvm::DenseSet<BoolValue *> &Constraints,
+ llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames = {{}});
+
/// Returns a string representation for `Constraints` - a collection of boolean
/// formulas and the `Result` of satisfiability checking.
///
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index cd87e87a6acab..5105999741e6a 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -14,7 +14,9 @@
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/Analysis/FlowSensitive/DebugSupport.h"
#include "clang/Analysis/FlowSensitive/Value.h"
+#include "llvm/Support/Debug.h"
#include <cassert>
#include <memory>
#include <utility>
@@ -293,6 +295,17 @@ BoolValue &DataflowAnalysisContext::buildAndSubstituteFlowConditionWithCache(
return substituteBoolValue(*ConstraintsIT->second, SubstitutionsCache);
}
+void DataflowAnalysisContext::dumpFlowCondition(AtomicBoolValue &Token) {
+ llvm::DenseSet<BoolValue *> Constraints = {&Token};
+ llvm::DenseSet<AtomicBoolValue *> VisitedTokens;
+ addTransitiveFlowConditionConstraints(Token, Constraints, VisitedTokens);
+
+ llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames = {
+ {&getBoolLiteralValue(false), "False"},
+ {&getBoolLiteralValue(true), "True"}};
+ llvm::dbgs() << debugString(Constraints, AtomNames);
+}
+
} // namespace dataflow
} // namespace clang
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 3aea670f20aa2..2b6cd0c4f8571 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -15,10 +15,8 @@
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -512,5 +510,9 @@ bool Environment::flowConditionImplies(BoolValue &Val) const {
return DACtx->flowConditionImplies(*FlowConditionToken, Val);
}
+void Environment::dump() const {
+ DACtx->dumpFlowCondition(*FlowConditionToken);
+}
+
} // namespace dataflow
} // namespace clang
diff --git a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
index f4217fd04c498..309ff0682f50d 100644
--- a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
@@ -17,6 +17,7 @@
#include "clang/Analysis/FlowSensitive/Solver.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatAdapters.h"
@@ -102,6 +103,22 @@ class DebugStringGenerator {
return formatv("{0}", fmt_pad(S, Indent, 0));
}
+ std::string debugString(const llvm::DenseSet<BoolValue *> &Constraints) {
+ std::vector<std::string> ConstraintsStrings;
+ ConstraintsStrings.reserve(Constraints.size());
+ for (BoolValue *Constraint : Constraints) {
+ ConstraintsStrings.push_back(debugString(*Constraint));
+ }
+ llvm::sort(ConstraintsStrings);
+
+ std::string Result;
+ for (const std::string &S : ConstraintsStrings) {
+ Result += S;
+ Result += '\n';
+ }
+ return Result;
+ }
+
/// Returns a string representation of a set of boolean `Constraints` and the
/// `Result` of satisfiability checking on the `Constraints`.
std::string debugString(ArrayRef<BoolValue *> &Constraints,
@@ -151,7 +168,7 @@ Constraints
clang::dataflow::debugString(AtomAssignment.second));
Lines.push_back(Line);
}
- llvm::sort(Lines.begin(), Lines.end());
+ llvm::sort(Lines);
return formatv("{0:$[\n]}", llvm::make_range(Lines.begin(), Lines.end()));
}
@@ -182,6 +199,12 @@ debugString(const BoolValue &B,
return DebugStringGenerator(std::move(AtomNames)).debugString(B);
}
+std::string
+debugString(const llvm::DenseSet<BoolValue *> &Constraints,
+ llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames) {
+ return DebugStringGenerator(std::move(AtomNames)).debugString(Constraints);
+}
+
std::string
debugString(ArrayRef<BoolValue *> Constraints, const Solver::Result &Result,
llvm::DenseMap<const AtomicBoolValue *, std::string> AtomNames) {
diff --git a/clang/unittests/Analysis/FlowSensitive/DebugSupportTest.cpp b/clang/unittests/Analysis/FlowSensitive/DebugSupportTest.cpp
index d59de0a343822..6b9321babfa64 100644
--- a/clang/unittests/Analysis/FlowSensitive/DebugSupportTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DebugSupportTest.cpp
@@ -188,6 +188,31 @@ TEST(BoolValueDebugStringTest, ComplexBooleanWithSomeNames) {
StrEq(Expected));
}
+TEST(ConstraintSetDebugStringTest, Empty) {
+ llvm::DenseSet<BoolValue *> Constraints;
+ EXPECT_THAT(debugString(Constraints), StrEq(""));
+}
+
+TEST(ConstraintSetDebugStringTest, Simple) {
+ ConstraintContext Ctx;
+ llvm::DenseSet<BoolValue *> Constraints;
+ auto X = cast<AtomicBoolValue>(Ctx.atom());
+ auto Y = cast<AtomicBoolValue>(Ctx.atom());
+ Constraints.insert(Ctx.disj(X, Y));
+ Constraints.insert(Ctx.disj(X, Ctx.neg(Y)));
+
+ auto Expected = R"((or
+ X
+ (not
+ Y))
+(or
+ X
+ Y)
+)";
+ EXPECT_THAT(debugString(Constraints, {{X, "X"}, {Y, "Y"}}),
+ StrEq(Expected));
+}
+
Solver::Result CheckSAT(std::vector<BoolValue *> Constraints) {
llvm::DenseSet<BoolValue *> ConstraintsSet(Constraints.begin(),
Constraints.end());
More information about the cfe-commits
mailing list