Merge pull request #2412 from Cornelius-Riemenschneider/nullness-corr-cond

Java: Nullness library: track instanceof expressions in correlated conditions
This commit is contained in:
Anders Schack-Mulligen
2019-11-26 10:33:34 +01:00
committed by GitHub
3 changed files with 74 additions and 0 deletions

View File

@@ -24,6 +24,21 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
)
}
/** Gets an instanceof expression of `v` with type `type` */
InstanceOfExpr instanceofExpr(SsaVariable v, Type type) {
result.getTypeName().getType() = type and
result.getExpr() = v.getAUse()
}
/**
* Gets an expression of the form `v1 == v2` or `v1 != v2`.
* The predicate is symmetric in `v1` and `v2`.
*/
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
result.hasOperands(v1.getAUse(), v2.getAUse()) and
isEqualExpr = result.polarity()
}
/** Gets an expression that is provably not `null`. */
Expr clearlyNotNullExpr(Expr reason) {
result instanceof ClassInstanceExpr and reason = result

View File

@@ -515,6 +515,18 @@ private predicate correlatedConditions(
cond2.getCondition() = enumConstEquality(v.getAUse(), pol2, c) and
inverted = pol1.booleanXor(pol2)
)
or
exists(SsaVariable v, Type type |
cond1.getCondition() = instanceofExpr(v, type) and
cond2.getCondition() = instanceofExpr(v, type) and
inverted = false
)
or
exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
cond1.getCondition() = varEqualityTestExpr(v1, v2, branch1) and
cond2.getCondition() = varEqualityTestExpr(v1, v2, branch2) and
inverted = branch1.booleanXor(branch2)
)
)
}

View File

@@ -324,4 +324,51 @@ public class B {
if (x != null) y.hashCode(); // OK
if (y != null) x.hashCode(); // OK
}
public void corrConds3(Object y) {
Object x = null;
if(y instanceof String) {
x = new Object();
}
if(y instanceof String) {
x.hashCode(); // OK
}
}
public void corrConds4(Object y) {
Object x = null;
if(!(y instanceof String)) {
x = new Object();
}
if(!(y instanceof String)) {
x.hashCode(); // OK
}
}
public void corrConds5(Object y, Object z) {
Object x = null;
if(y == z) {
x = new Object();
}
if(y == z) {
x.hashCode(); // OK
}
Object x2 = null;
if(y != z) {
x2 = new Object();
}
if(y != z) {
x2.hashCode(); // OK
}
Object x3 = null;
if(y != z) {
x3 = new Object();
}
if(!(y == z)) {
x3.hashCode(); // OK
}
}
}