aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp')
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp63
1 files changed, 36 insertions, 27 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index 47a994f..e81048c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -104,6 +104,13 @@ DataflowAnalysisContext::getOrCreateNullPointerValue(QualType PointeeType) {
return *Res.first->second;
}
+void DataflowAnalysisContext::addInvariant(const Formula &Constraint) {
+ if (Invariant == nullptr)
+ Invariant = &Constraint;
+ else
+ Invariant = &arena().makeAnd(*Invariant, Constraint);
+}
+
void DataflowAnalysisContext::addFlowConditionConstraint(
Atom Token, const Formula &Constraint) {
auto Res = FlowConditionConstraints.try_emplace(Token, &Constraint);
@@ -149,8 +156,7 @@ bool DataflowAnalysisContext::flowConditionImplies(Atom Token,
llvm::SetVector<const Formula *> Constraints;
Constraints.insert(&arena().makeAtomRef(Token));
Constraints.insert(&arena().makeNot(Val));
- llvm::DenseSet<Atom> VisitedTokens;
- addTransitiveFlowConditionConstraints(Token, Constraints, VisitedTokens);
+ addTransitiveFlowConditionConstraints(Token, Constraints);
return isUnsatisfiable(std::move(Constraints));
}
@@ -159,8 +165,7 @@ bool DataflowAnalysisContext::flowConditionIsTautology(Atom Token) {
// ever be false.
llvm::SetVector<const Formula *> Constraints;
Constraints.insert(&arena().makeNot(arena().makeAtomRef(Token)));
- llvm::DenseSet<Atom> VisitedTokens;
- addTransitiveFlowConditionConstraints(Token, Constraints, VisitedTokens);
+ addTransitiveFlowConditionConstraints(Token, Constraints);
return isUnsatisfiable(std::move(Constraints));
}
@@ -172,28 +177,33 @@ bool DataflowAnalysisContext::equivalentFormulas(const Formula &Val1,
}
void DataflowAnalysisContext::addTransitiveFlowConditionConstraints(
- Atom Token, llvm::SetVector<const Formula *> &Constraints,
- llvm::DenseSet<Atom> &VisitedTokens) {
- auto Res = VisitedTokens.insert(Token);
- if (!Res.second)
- return;
-
- auto ConstraintsIt = FlowConditionConstraints.find(Token);
- if (ConstraintsIt == FlowConditionConstraints.end()) {
- Constraints.insert(&arena().makeAtomRef(Token));
- } else {
- // Bind flow condition token via `iff` to its set of constraints:
- // FC <=> (C1 ^ C2 ^ ...), where Ci are constraints
- Constraints.insert(&arena().makeEquals(arena().makeAtomRef(Token),
- *ConstraintsIt->second));
- }
-
- auto DepsIt = FlowConditionDeps.find(Token);
- if (DepsIt != FlowConditionDeps.end()) {
- for (Atom DepToken : DepsIt->second) {
- addTransitiveFlowConditionConstraints(DepToken, Constraints,
- VisitedTokens);
+ Atom Token, llvm::SetVector<const Formula *> &Constraints) {
+ llvm::DenseSet<Atom> AddedTokens;
+ std::vector<Atom> Remaining = {Token};
+
+ if (Invariant)
+ Constraints.insert(Invariant);
+ // Define all the flow conditions that might be referenced in constraints.
+ while (!Remaining.empty()) {
+ auto Token = Remaining.back();
+ Remaining.pop_back();
+ if (!AddedTokens.insert(Token).second)
+ continue;
+
+ auto ConstraintsIt = FlowConditionConstraints.find(Token);
+ if (ConstraintsIt == FlowConditionConstraints.end()) {
+ Constraints.insert(&arena().makeAtomRef(Token));
+ } else {
+ // Bind flow condition token via `iff` to its set of constraints:
+ // FC <=> (C1 ^ C2 ^ ...), where Ci are constraints
+ Constraints.insert(&arena().makeEquals(arena().makeAtomRef(Token),
+ *ConstraintsIt->second));
}
+
+ if (auto DepsIt = FlowConditionDeps.find(Token);
+ DepsIt != FlowConditionDeps.end())
+ for (Atom A : DepsIt->second)
+ Remaining.push_back(A);
}
}
@@ -201,8 +211,7 @@ void DataflowAnalysisContext::dumpFlowCondition(Atom Token,
llvm::raw_ostream &OS) {
llvm::SetVector<const Formula *> Constraints;
Constraints.insert(&arena().makeAtomRef(Token));
- llvm::DenseSet<Atom> VisitedTokens;
- addTransitiveFlowConditionConstraints(Token, Constraints, VisitedTokens);
+ addTransitiveFlowConditionConstraints(Token, Constraints);
// TODO: have formulas know about true/false directly instead
Atom True = arena().makeLiteral(true).getAtom();