Skip to content

Commit eb00dab

Browse files
committed
Java: Prepare TypeFlow for separate instantiation of universal flow.
1 parent ff80b24 commit eb00dab

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 |
@@ -132,7 +131,7 @@ private module Input implements TypeFlowInput<Location> {
132131
/**
133132
* Holds if `null` is the only value that flows to `n`.
134133
*/
135-
predicate isNullValue(TypeFlowNode n) {
134+
predicate isNullValue(FlowNode n) {
136135
n.asExpr() instanceof NullLiteral
137136
or
138137
exists(LocalVariableDeclExpr decl |
@@ -142,11 +141,21 @@ private module Input implements TypeFlowInput<Location> {
142141
)
143142
}
144143

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

151160
predicate exactTypeBase(TypeFlowNode n, RefType t) {
152161
exists(ClassInstanceExpr e |

0 commit comments

Comments
 (0)