Skip to content

Commit 7f86f8c

Browse files
committed
Java: Prepare TypeFlow for separate instantiation of universal flow.
1 parent 9f09454 commit 7f86f8c

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,25 @@ private import semmle.code.java.dispatch.VirtualDispatch
1313
private import semmle.code.java.dataflow.internal.BaseSSA
1414
private import semmle.code.java.controlflow.Guards
1515
private import codeql.typeflow.TypeFlow
16+
private import codeql.typeflow.UniversalFlow as UniversalFlow
1617

17-
private module Input implements TypeFlowInput<Location> {
18-
private newtype TTypeFlowNode =
18+
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
19+
private RefType boxIfNeeded(J::Type t) {
20+
t.(PrimitiveType).getBoxedType() = result or
21+
result = t
22+
}
23+
24+
module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
25+
private newtype TFlowNode =
1926
TField(Field f) { not f.getType() instanceof PrimitiveType } or
2027
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
2128
TExpr(Expr e) or
2229
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
2330

24-
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
25-
private RefType boxIfNeeded(J::Type t) {
26-
t.(PrimitiveType).getBoxedType() = result or
27-
result = t
28-
}
29-
3031
/**
3132
* A `Field`, `BaseSsaVariable`, `Expr`, or `Method`.
3233
*/
33-
class TypeFlowNode extends TTypeFlowNode {
34+
class FlowNode extends TFlowNode {
3435
string toString() {
3536
result = this.asField().toString() or
3637
result = this.asSsa().toString() or
@@ -61,8 +62,6 @@ private module Input implements TypeFlowInput<Location> {
6162
}
6263
}
6364

64-
class Type = RefType;
65-
6665
private SrcCallable viableCallable_v1(Call c) {
6766
result = viableImpl_v1(c)
6867
or
@@ -88,7 +87,7 @@ private module Input implements TypeFlowInput<Location> {
8887
*
8988
* For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`.
9089
*/
91-
predicate step(TypeFlowNode n1, TypeFlowNode n2) {
90+
predicate step(FlowNode n1, FlowNode n2) {
9291
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
9392
or
9493
exists(Field f, Expr e |
@@ -134,7 +133,7 @@ private module Input implements TypeFlowInput<Location> {
134133
/**
135134
* Holds if `null` is the only value that flows to `n`.
136135
*/
137-
predicate isNullValue(TypeFlowNode n) {
136+
predicate isNullValue(FlowNode n) {
138137
n.asExpr() instanceof NullLiteral
139138
or
140139
exists(LocalVariableDeclExpr decl |
@@ -144,11 +143,21 @@ private module Input implements TypeFlowInput<Location> {
144143
)
145144
}
146145

147-
predicate isExcludedFromNullAnalysis(TypeFlowNode n) {
146+
predicate isExcludedFromNullAnalysis(FlowNode n) {
148147
// Fields that are never assigned a non-null value are probably set by
149148
// reflection and are thus not always null.
150149
exists(n.asField())
151150
}
151+
}
152+
153+
private module Input implements TypeFlowInput<Location> {
154+
import FlowStepsInput
155+
156+
class TypeFlowNode = FlowNode;
157+
158+
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
159+
160+
class Type = RefType;
152161

153162
predicate exactTypeBase(TypeFlowNode n, RefType t) {
154163
exists(ClassInstanceExpr e |

0 commit comments

Comments
 (0)