mirror of
https://github.com/github/codeql.git
synced 2026-06-19 03:41:07 +02:00
Merge pull request #21987 from hvitved/type-flow-ranking
Java: Fix performance issue in type flow library
This commit is contained in:
@@ -72,6 +72,35 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
private class FlowNodeElement extends Element {
|
||||
FlowNodeElement() {
|
||||
this instanceof Field or
|
||||
this instanceof Expr or
|
||||
this instanceof Method
|
||||
}
|
||||
}
|
||||
|
||||
private predicate id(FlowNodeElement x, FlowNodeElement y) { x = y }
|
||||
|
||||
private predicate idOf(FlowNodeElement x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
|
||||
int getFlowNodeId(FlowNode n) {
|
||||
n =
|
||||
rank[result](FlowNode n0, int a, int b |
|
||||
a = 0 and
|
||||
idOf(n0.asField(), b)
|
||||
or
|
||||
// no case for `n0.asSsa()`; here we rely on the built-in location-based ranking
|
||||
a = 1 and
|
||||
idOf(n0.asExpr(), b)
|
||||
or
|
||||
a = 2 and
|
||||
idOf(n0.asMethod(), b)
|
||||
|
|
||||
n0 order by a, b
|
||||
)
|
||||
}
|
||||
|
||||
private SrcCallable viableCallable_v1(Call c) {
|
||||
result = viableImpl_v1(c)
|
||||
or
|
||||
@@ -165,6 +194,8 @@ private module Input implements TypeFlowInput<Location> {
|
||||
|
||||
class TypeFlowNode = FlowNode;
|
||||
|
||||
predicate getTypeFlowNodeId = FlowStepsInput::getFlowNodeId/1;
|
||||
|
||||
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
|
||||
|
||||
class Type = RefType;
|
||||
|
||||
@@ -170,6 +170,8 @@ private class EmptyCollectionConstructor extends Constructor {
|
||||
private module CollectionFlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
import FlowStepsInput
|
||||
|
||||
predicate getFlowNodeId = FlowStepsInput::getFlowNodeId/1;
|
||||
|
||||
/**
|
||||
* Holds if `n2` is a collection/array/constant whose value(s) are
|
||||
* determined completely from the range of `n1` nodes.
|
||||
|
||||
@@ -29,6 +29,12 @@ signature module TypeFlowInput<LocationSig Location> {
|
||||
Location getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an identifier for node `n`, if any. When no identifier is provided for `n`,
|
||||
* the library falls back to location-based ranking.
|
||||
*/
|
||||
default int getTypeFlowNodeId(TypeFlowNode n) { none() }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `n1` to `n2` in one step.
|
||||
*
|
||||
|
||||
@@ -45,6 +45,12 @@ signature module UniversalFlowInput<LocationSig Location> {
|
||||
Location getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an identifier for node `n`, if any. When no identifier is provided for `n`,
|
||||
* the library falls back to location-based ranking.
|
||||
*/
|
||||
default int getFlowNodeId(FlowNode n) { none() }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `n1` to `n2` in one step.
|
||||
*
|
||||
@@ -149,17 +155,44 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
|
||||
private module RankEdge<Edge E> implements RankedEdge<E::Node> {
|
||||
private import E
|
||||
|
||||
private predicate needsNodeId(FlowNode n) { edge(n, _) }
|
||||
|
||||
private int getFlowNodeIdByLoc(FlowNode n) {
|
||||
n =
|
||||
rank[result](FlowNode n0, string filePath, int startline, int startcolumn |
|
||||
needsNodeId(n0) and
|
||||
not exists(getFlowNodeId(n0)) and
|
||||
n0.getLocation().hasLocationInfo(filePath, startline, startcolumn, _, _)
|
||||
|
|
||||
n0 order by filePath, startline, startcolumn
|
||||
)
|
||||
}
|
||||
|
||||
private int getFlowNodeIdExt(FlowNode n) {
|
||||
n =
|
||||
rank[result](FlowNode n0, int a, int b |
|
||||
needsNodeId(n0) and
|
||||
a = 0 and
|
||||
b = getFlowNodeId(n0)
|
||||
or
|
||||
a = 1 and
|
||||
b = getFlowNodeIdByLoc(n0)
|
||||
|
|
||||
n0 order by a, b
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, FlowNode n1, Node n2) {
|
||||
n1 =
|
||||
rank[r](FlowNode n, int startline, int startcolumn |
|
||||
rank[r](FlowNode n, int id |
|
||||
edge(n, n2) and
|
||||
n.getLocation().hasLocationInfo(_, startline, startcolumn, _, _)
|
||||
id = getFlowNodeIdExt(n)
|
||||
|
|
||||
n order by startline, startcolumn
|
||||
n order by id
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ module TypeFlow<LocationSig Location, TypeFlowInput<Location> I> {
|
||||
private module UfInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
class FlowNode = TypeFlowNode;
|
||||
|
||||
predicate getFlowNodeId = I::getTypeFlowNodeId/1;
|
||||
|
||||
predicate step = I::step/2;
|
||||
|
||||
predicate isNullValue = I::isNullValue/1;
|
||||
|
||||
Reference in New Issue
Block a user