UniversalFlow: Rename node type.

This commit is contained in:
Anders Schack-Mulligen
2024-10-28 16:23:44 +01:00
parent 1aecdb44dc
commit d6e420bd0e
2 changed files with 43 additions and 43 deletions

View File

@@ -7,7 +7,7 @@ signature module UniversalFlowInput<LocationSig Location> {
* A node for which certain data flow properties may be proved. For example,
* expressions and method declarations.
*/
class TypeFlowNode {
class FlowNode {
/** Gets a textual representation of this node. */
string toString();
@@ -20,16 +20,16 @@ signature module UniversalFlowInput<LocationSig Location> {
*
* For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`.
*/
predicate step(TypeFlowNode n1, TypeFlowNode n2);
predicate step(FlowNode n1, FlowNode n2);
/** Holds if `n` represents a `null` value. */
predicate isNullValue(TypeFlowNode n);
predicate isNullValue(FlowNode n);
/**
* Holds if `n` should be excluded from the set of null values even if
* the null analysis determines that `n` is always null.
*/
default predicate isExcludedFromNullAnalysis(TypeFlowNode n) { none() }
default predicate isExcludedFromNullAnalysis(FlowNode n) { none() }
}
module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
@@ -39,21 +39,21 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
* Holds if data can flow from `n1` to `n2` in one step, and `n1` is
* functionally determined by `n2`.
*/
private predicate uniqStep(TypeFlowNode n1, TypeFlowNode n2) { n1 = unique(TypeFlowNode n | step(n, n2)) }
private predicate uniqStep(FlowNode n1, FlowNode n2) { n1 = unique(FlowNode n | step(n, n2)) }
/**
* Holds if data can flow from `n1` to `n2` in one step, and `n1` is not
* functionally determined by `n2`.
*/
private predicate joinStep(TypeFlowNode n1, TypeFlowNode n2) { step(n1, n2) and not uniqStep(n1, n2) }
private predicate joinStep(FlowNode n1, FlowNode n2) { step(n1, n2) and not uniqStep(n1, n2) }
/** Holds if `null` is the only value that flows to `n`. */
private predicate isNull(TypeFlowNode n) {
private predicate isNull(FlowNode n) {
isNullValue(n)
or
exists(TypeFlowNode mid | isNull(mid) and uniqStep(mid, n))
exists(FlowNode mid | isNull(mid) and uniqStep(mid, n))
or
forex(TypeFlowNode mid | joinStep(mid, n) | isNull(mid)) and
forex(FlowNode mid | joinStep(mid, n) | isNull(mid)) and
not isExcludedFromNullAnalysis(n)
}
@@ -61,27 +61,27 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
* Holds if data can flow from `n1` to `n2` in one step, `n1` is not necessarily
* functionally determined by `n2`, and `n1` might take a non-null value.
*/
predicate joinStepNotNull(TypeFlowNode n1, TypeFlowNode n2) {
predicate joinStepNotNull(FlowNode n1, FlowNode n2) {
joinStep(n1, n2) and not isNull(n1)
}
predicate anyStep(TypeFlowNode n1, TypeFlowNode n2) {
predicate anyStep(FlowNode n1, FlowNode n2) {
joinStepNotNull(n1, n2) or uniqStep(n1, n2)
}
private predicate sccEdge(TypeFlowNode n1, TypeFlowNode n2) {
private predicate sccEdge(FlowNode n1, FlowNode n2) {
anyStep(n1, n2) and anyStep+(n2, n1)
}
private module Scc = QlBuiltins::EquivalenceRelation<TypeFlowNode, sccEdge/2>;
private module Scc = QlBuiltins::EquivalenceRelation<FlowNode, sccEdge/2>;
private class TypeFlowScc = Scc::EquivalenceClass;
/** Holds if `n` is part of an SCC of size 2 or more represented by `scc`. */
private predicate sccRepr(TypeFlowNode n, TypeFlowScc scc) { scc = Scc::getEquivalenceClass(n) }
private predicate sccRepr(FlowNode n, TypeFlowScc scc) { scc = Scc::getEquivalenceClass(n) }
private predicate sccJoinStepNotNull(TypeFlowNode n, TypeFlowScc scc) {
exists(TypeFlowNode mid |
private predicate sccJoinStepNotNull(FlowNode n, TypeFlowScc scc) {
exists(FlowNode mid |
joinStepNotNull(n, mid) and
sccRepr(mid, scc) and
not sccRepr(n, scc)
@@ -93,11 +93,11 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
private signature module Edge {
class Node;
predicate edge(TypeFlowNode n1, Node n2);
predicate edge(FlowNode n1, Node n2);
}
private signature module RankedEdge<NodeSig Node> {
predicate edgeRank(int r, TypeFlowNode n1, Node n2);
predicate edgeRank(int r, FlowNode n1, Node n2);
int lastRank(Node n);
}
@@ -109,9 +109,9 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
* Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. The used
* ordering is not necessarily total, so the ranking may have gaps.
*/
private predicate edgeRank1(int r, TypeFlowNode n1, Node n2) {
private predicate edgeRank1(int r, FlowNode n1, Node n2) {
n1 =
rank[r](TypeFlowNode n, int startline, int startcolumn |
rank[r](FlowNode n, int startline, int startcolumn |
edge(n, n2) and
n.getLocation().hasLocationInfo(_, startline, startcolumn, _, _)
|
@@ -128,7 +128,7 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
}
/** Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. */
predicate edgeRank(int r, TypeFlowNode n1, Node n2) {
predicate edgeRank(int r, FlowNode n1, Node n2) {
exists(int r1 |
edgeRank1(r1, n1, n2) and
edgeRank2(r, r1, n2)
@@ -141,10 +141,10 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
private signature module TypePropagation {
class Typ;
predicate candType(TypeFlowNode n, Typ t);
predicate candType(FlowNode n, Typ t);
bindingset[t]
predicate supportsType(TypeFlowNode n, Typ t);
predicate supportsType(FlowNode n, Typ t);
}
/** Implements recursion through `forall` by way of edge ranking. */
@@ -155,7 +155,7 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
*/
pragma[nomagic]
private predicate candJoinType(Node n, T::Typ t) {
exists(TypeFlowNode mid |
exists(FlowNode mid |
T::candType(mid, t) and
E::edgeRank(_, mid, n)
)
@@ -171,7 +171,7 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
or
flowJoin(r - 1, n, t) and E::edgeRank(r, _, n)
) and
forall(TypeFlowNode mid | E::edgeRank(r, mid, n) | T::supportsType(mid, t))
forall(FlowNode mid | E::edgeRank(r, mid, n) | T::supportsType(mid, t))
}
/**
@@ -183,7 +183,7 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
}
private module JoinStep implements Edge {
class Node = TypeFlowNode;
class Node = FlowNode;
predicate edge = joinStepNotNull/2;
}
@@ -199,35 +199,35 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
private module RankedSccJoinStep = RankEdge<SccJoinStep>;
signature module NullaryPropertySig {
predicate hasPropertyBase(TypeFlowNode n);
predicate hasPropertyBase(FlowNode n);
default predicate barrier(TypeFlowNode n) { none() }
default predicate barrier(FlowNode n) { none() }
}
module FlowNullary<NullaryPropertySig P> {
private module Propagation implements TypePropagation {
class Typ = Unit;
predicate candType(TypeFlowNode n, Unit u) { hasProperty(n) and exists(u) }
predicate candType(FlowNode n, Unit u) { hasProperty(n) and exists(u) }
predicate supportsType = candType/2;
}
predicate hasProperty(TypeFlowNode n) {
predicate hasProperty(FlowNode n) {
P::hasPropertyBase(n)
or
not P::barrier(n) and
(
exists(TypeFlowNode mid | hasProperty(mid) and uniqStep(mid, n))
exists(FlowNode mid | hasProperty(mid) and uniqStep(mid, n))
or
// The following is an optimized version of
// `forex(TypeFlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid))`
ForAll<TypeFlowNode, RankedJoinStep, Propagation>::flowJoin(n, _)
// `forex(FlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid))`
ForAll<FlowNode, RankedJoinStep, Propagation>::flowJoin(n, _)
or
exists(TypeFlowScc scc |
sccRepr(n, scc) and
// Optimized version of
// `forex(TypeFlowNode mid | sccJoinStepNotNull(mid, scc) | hasPropery(mid))`
// `forex(FlowNode mid | sccJoinStepNotNull(mid, scc) | hasPropery(mid))`
ForAll<TypeFlowScc, RankedSccJoinStep, Propagation>::flowJoin(scc, _)
)
)
@@ -240,9 +240,9 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
bindingset[t1, t2]
default predicate propImplies(Prop t1, Prop t2) { t1 = t2 }
predicate hasPropertyBase(TypeFlowNode n, Prop t);
predicate hasPropertyBase(FlowNode n, Prop t);
default predicate barrier(TypeFlowNode n) { none() }
default predicate barrier(FlowNode n) { none() }
}
module Flow<PropertySig P> {
@@ -252,7 +252,7 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
predicate candType = hasProperty/2;
bindingset[t]
predicate supportsType(TypeFlowNode n, Typ t) {
predicate supportsType(FlowNode n, Typ t) {
exists(Typ t0 | hasProperty(n, t0) and P::propImplies(t0, t))
}
}
@@ -261,21 +261,21 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
* Holds if the runtime type of `n` is exactly `t` and if this bound is a
* non-trivial lower bound, that is, `t` has a subtype.
*/
predicate hasProperty(TypeFlowNode n, P::Prop t) {
predicate hasProperty(FlowNode n, P::Prop t) {
P::hasPropertyBase(n, t)
or
not P::barrier(n) and
(
exists(TypeFlowNode mid | hasProperty(mid, t) and uniqStep(mid, n))
exists(FlowNode mid | hasProperty(mid, t) and uniqStep(mid, n))
or
// The following is an optimized version of
// `forex(TypeFlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid, t))`
ForAll<TypeFlowNode, RankedJoinStep, Propagation>::flowJoin(n, t)
// `forex(FlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid, t))`
ForAll<FlowNode, RankedJoinStep, Propagation>::flowJoin(n, t)
or
exists(TypeFlowScc scc |
sccRepr(n, scc) and
// Optimized version of
// `forex(TypeFlowNode mid | sccJoinStepNotNull(mid, scc) | hasPropery(mid, t))`
// `forex(FlowNode mid | sccJoinStepNotNull(mid, scc) | hasPropery(mid, t))`
ForAll<TypeFlowScc, RankedSccJoinStep, Propagation>::flowJoin(scc, t)
)
)

View File

@@ -7,7 +7,7 @@ module TypeFlow<LocationSig Location, TypeFlowInput<Location> I> {
private import I
private module UfInput implements UniversalFlowInput<Location> {
class TypeFlowNode = I::TypeFlowNode;
class FlowNode = TypeFlowNode;
predicate step = I::step/2;