Skip to content

Commit 34fdfe4

Browse files
committed
Java: Prune nodes in DispatchFlow based on their types.
1 parent df4bd36 commit 34fdfe4

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ private Callable dispatchCand(Call c) {
1818
result = viableImpl_inp(c)
1919
}
2020

21+
/** Holds if `t` is a type that is relevant for dispatch flow. */
22+
predicate relevant(RefType t) {
23+
exists(ClassInstanceExpr cie | dispatchOrigin(cie, _, _) and t = cie.getConstructedType().getSourceDeclaration()) or
24+
relevant(t.getErasure()) or
25+
exists(RefType r | relevant(r) and t = r.getASourceSupertype()) or
26+
relevant(t.(Array).getComponentType()) or
27+
t instanceof MapType or
28+
t instanceof CollectionType
29+
}
30+
31+
/** A node with a type that is relevant for dispatch flow. */
32+
class RelevantNode extends Node {
33+
RelevantNode() { relevant(this.getType()) }
34+
}
35+
2136
/**
2237
* Holds if `p` is the `i`th parameter of a viable dispatch target of `call`.
2338
* The instance parameter is considered to have index `-1`.
@@ -26,7 +41,8 @@ pragma[nomagic]
2641
private predicate viableParamCand(Call call, int i, ParameterNode p) {
2742
exists(Callable callable |
2843
callable = dispatchCand(call) and
29-
p.isParameterOf(callable, i)
44+
p.isParameterOf(callable, i) and
45+
p instanceof RelevantNode
3046
)
3147
}
3248

@@ -43,7 +59,7 @@ private predicate viableArgParamCand(ArgumentNode arg, ParameterNode p) {
4359
/**
4460
* Holds if data may flow from `n1` to `n2` in a single step through a call or a return.
4561
*/
46-
private predicate callFlowStepCand(Node n1, Node n2) {
62+
private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) {
4763
exists(ReturnStmt ret, Method m |
4864
ret.getEnclosingCallable() = m and
4965
ret.getResult() = n1.asExpr() and
@@ -56,7 +72,7 @@ private predicate callFlowStepCand(Node n1, Node n2) {
5672
* Holds if data may flow from `n1` to `n2` in a single step that does not go
5773
* through a call or a return.
5874
*/
59-
private predicate flowStep(Node n1, Node n2) {
75+
private predicate flowStep(RelevantNode n1, RelevantNode n2) {
6076
exists(BaseSsaVariable v, BaseSsaVariable def |
6177
def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() or
6278
def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) or

0 commit comments

Comments
 (0)