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 47cc4115b7ac..c70bf120bc66 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
@@ -1298,13 +1298,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
final int idPlain = varPlain.getID();
final int idNegated = varNegated == null ? -1 : varNegated.getID();
- if(isNull(varPlain) || isNotNull(varPlain)) {
- DfaVariableState state = myVariableStates.get(varPlain);
- if (state != null) {
- setVariableState(varPlain, state.withoutFact(DfaFactType.CAN_BE_NULL));
- }
- }
-
int[] classes = myIdToEqClassesIndices.get(idPlain);
int[] negatedClasses = myIdToEqClassesIndices.get(idNegated);
int[] result = ArrayUtil
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
index 7df042704c05..0f8932dd6ecf 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
@@ -665,6 +665,10 @@ class StateMerger {
@Override
void removeFromState(@NotNull DfaMemoryStateImpl state) {
+ if(!myPositive && state.isNotNull(myVar) && state.isNull(myArg)) {
+ // merging "x == null" and "x != null" should be possible with marking "x" as nullable
+ state.forceVariableFact(myVar, CAN_BE_NULL, true);
+ }
state.removeEquivalenceRelations(myVar);
}
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NullabilityBasics.java b/java/java-tests/testData/inspection/dataFlow/fixture/NullabilityBasics.java
new file mode 100644
index 000000000000..25dbaf2f37c1
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/NullabilityBasics.java
@@ -0,0 +1,31 @@
+import org.jetbrains.annotations.*;
+
+class NullabilityBasics {
+
+ void test2() {
+ String x = getNullable();
+ if (x == null) {
+ System.out.println("x is null!");
+ }
+ if (isEmpty(x) && Math.random() > 0.5) {
+ return;
+ }
+ System.out.println(x.trim());
+ }
+
+ @Nullable String getNullable() {
+ return Math.random() > 0.5 ? null : "";
+ }
+
+ @Contract(value = "null -> true",pure = true)
+ static boolean isEmpty(@Nullable String s) {
+ return s == null || s.isEmpty();
+ }
+
+ void test(String x) {
+ if (x == null) {
+ System.out.println("x is null!");
+ }
+ System.out.println(x.trim());
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
index 76cf4cd7774b..bcd2171cecb1 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
@@ -582,4 +582,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
public void testPrimitiveNull() { doTest(); }
public void testLessThanRelations() { doTest(); }
public void testAdvancedArrayAccess() { doTest(); }
+ public void testNullabilityBasics() { doTest(); }
}