dfa: handle variable comparisons to unknown not-null values

This commit is contained in:
peter
2014-06-17 19:43:42 +02:00
parent 7b346dae4e
commit 88c8ac79e5
6 changed files with 61 additions and 2 deletions
@@ -583,7 +583,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
if (dfaLeft instanceof DfaVariableValue) {
DfaVariableValue dfaVar = (DfaVariableValue)dfaLeft;
if (isUnknownState(dfaVar)) return true;
if (!dfaRelation.isInstanceOf()) {
if (((DfaTypeValue)dfaRight).isNotNull() && isNull(dfaVar)) {
return isNegated;
}
return true;
}
if (isNegated) {
DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue)dfaRight);
if (newState != null) {
@@ -52,7 +52,6 @@ public class DfaRelationValue extends DfaValue {
}
public DfaRelationValue createRelation(DfaValue dfaLeft, DfaValue dfaRight, IElementType relation, boolean negated) {
if (dfaRight instanceof DfaTypeValue && INSTANCEOF_KEYWORD != relation) return null;
if (PLUS == relation) return null;
if (dfaLeft instanceof DfaVariableValue || dfaLeft instanceof DfaBoxedValue || dfaLeft instanceof DfaUnboxedValue
@@ -169,6 +168,10 @@ public class DfaRelationValue extends DfaValue {
return myRelation == EQEQ && myIsNegated || myRelation == GT && !myIsNegated || myRelation == GE && myIsNegated;
}
public boolean isInstanceOf() {
return myRelation == INSTANCEOF_KEYWORD;
}
@NonNls public String toString() {
return (isNegated() ? "not " : "") + myLeftOperand + " " + myRelation + " " + myRightOperand;
}
@@ -0,0 +1,14 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
class Bar3 {
public void foo(@Nullable Object element) {
final String elementType = element != null ? element.toString() : null;
if (elementType == "") {
System.out.println(element.hashCode());
}
}
}
@@ -0,0 +1,16 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
class Bar3 {
public void foo(@Nullable Object element) {
final String elementType = element != null ? element.toString() : null;
if (elementType == nullableString()) {
System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
}
}
@Nullable String nullableString() { return null; }
}
@@ -0,0 +1,16 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
class Bar3 {
public void foo(@Nullable Object element) {
final String elementType = element != null ? element.toString() : null;
if (elementType == someString()) {
System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
}
}
String someString() { return <warning descr="'null' is returned by the method which is not declared as @Nullable">null</warning>; }
}
@@ -71,6 +71,9 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testGeneratedEquals() throws Throwable { doTest(); }
public void testIDEA84489() throws Throwable { doTest(); }
public void testComparingNullToNotNull() { doTest(); }
public void testComparingNullableToNullable() { doTest(); }
public void testComparingNullableToUnknown() { doTest(); }
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
public void testComparingToNullableShouldNotAffectNullity() throws Throwable { doTest(); }
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }