diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index 3b44c82f9398..1b6d1dfedfec 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -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) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
index 8343fc9e6a2c..3e70b2d4b673 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
@@ -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;
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java
new file mode 100644
index 000000000000..a9f17f7e9a06
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java
@@ -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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java
new file mode 100644
index 000000000000..5e3ce3c0b69b
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java
@@ -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(element.hashCode());
+ }
+ }
+
+ @Nullable String nullableString() { return null; }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java
new file mode 100644
index 000000000000..b15c6c7a52f7
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java
@@ -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(element.hashCode());
+ }
+ }
+
+ String someString() { return null; }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index d15527e3c49c..833b5196d74a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -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(); }