Skip to content

Commit 18e1708

Browse files
authored
Merge pull request #2412 from Cornelius-Riemenschneider/nullness-corr-cond
Java: Nullness library: track instanceof expressions in correlated conditions
2 parents fb44aa1 + 37f1621 commit 18e1708

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

java/ql/src/semmle/code/java/dataflow/NullGuards.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
2424
)
2525
}
2626

27+
/** Gets an instanceof expression of `v` with type `type` */
28+
InstanceOfExpr instanceofExpr(SsaVariable v, Type type) {
29+
result.getTypeName().getType() = type and
30+
result.getExpr() = v.getAUse()
31+
}
32+
33+
/**
34+
* Gets an expression of the form `v1 == v2` or `v1 != v2`.
35+
* The predicate is symmetric in `v1` and `v2`.
36+
*/
37+
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
38+
result.hasOperands(v1.getAUse(), v2.getAUse()) and
39+
isEqualExpr = result.polarity()
40+
}
41+
2742
/** Gets an expression that is provably not `null`. */
2843
Expr clearlyNotNullExpr(Expr reason) {
2944
result instanceof ClassInstanceExpr and reason = result

java/ql/src/semmle/code/java/dataflow/Nullness.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,18 @@ private predicate correlatedConditions(
515515
cond2.getCondition() = enumConstEquality(v.getAUse(), pol2, c) and
516516
inverted = pol1.booleanXor(pol2)
517517
)
518+
or
519+
exists(SsaVariable v, Type type |
520+
cond1.getCondition() = instanceofExpr(v, type) and
521+
cond2.getCondition() = instanceofExpr(v, type) and
522+
inverted = false
523+
)
524+
or
525+
exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
526+
cond1.getCondition() = varEqualityTestExpr(v1, v2, branch1) and
527+
cond2.getCondition() = varEqualityTestExpr(v1, v2, branch2) and
528+
inverted = branch1.booleanXor(branch2)
529+
)
518530
)
519531
}
520532

java/ql/test/query-tests/Nullness/B.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,4 +324,51 @@ public void corrConds2(Object x, Object y) {
324324
if (x != null) y.hashCode(); // OK
325325
if (y != null) x.hashCode(); // OK
326326
}
327+
328+
public void corrConds3(Object y) {
329+
Object x = null;
330+
if(y instanceof String) {
331+
x = new Object();
332+
}
333+
if(y instanceof String) {
334+
x.hashCode(); // OK
335+
}
336+
}
337+
338+
public void corrConds4(Object y) {
339+
Object x = null;
340+
if(!(y instanceof String)) {
341+
x = new Object();
342+
}
343+
if(!(y instanceof String)) {
344+
x.hashCode(); // OK
345+
}
346+
}
347+
348+
public void corrConds5(Object y, Object z) {
349+
Object x = null;
350+
if(y == z) {
351+
x = new Object();
352+
}
353+
if(y == z) {
354+
x.hashCode(); // OK
355+
}
356+
357+
Object x2 = null;
358+
if(y != z) {
359+
x2 = new Object();
360+
}
361+
if(y != z) {
362+
x2.hashCode(); // OK
363+
}
364+
365+
Object x3 = null;
366+
if(y != z) {
367+
x3 = new Object();
368+
}
369+
if(!(y == z)) {
370+
x3.hashCode(); // OK
371+
}
372+
}
373+
327374
}

0 commit comments

Comments
 (0)