From f2c828e9d88cfacda85e4ce0721244acbf351985 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 27 Oct 2023 14:02:46 +0200 Subject: [PATCH] [java-dfa] Do not drop NULLABLE when updating dependent variables. Attempt to fix IDEA-336371 False Negative NPE after instanceof check GitOrigin-RevId: 1539e33119f58bcd58f20d9015b7c8092d79d02b --- .../NullWarningAfterInstanceofCheck.java | 21 +++++++++++++++++++ .../DataFlowInspectionTest.java | 1 + .../dataFlow/memory/DfaMemoryStateImpl.java | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/NullWarningAfterInstanceofCheck.java diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NullWarningAfterInstanceofCheck.java b/java/java-tests/testData/inspection/dataFlow/fixture/NullWarningAfterInstanceofCheck.java new file mode 100644 index 000000000000..4615a2bd810d --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/NullWarningAfterInstanceofCheck.java @@ -0,0 +1,21 @@ +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +final class NullFP { + void test(@NotNull Y y) {} + + interface X { + @Contract(pure = true) + @Nullable Y getY(); + } + + interface Y {} + interface Z extends Y {} + + void run(@NotNull final X x) { + final Y y = x.getY(); + if (y instanceof Z) {} + test(x.getY()); + } +} 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 5b70b52c8fb0..dcd780f9ab5e 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -734,4 +734,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testDuplicatedByPointlessBooleanInspection() { doTest(); } public void testSystemOutNullSource() { doTest(); } public void testPrimitiveTypeFieldInWrapper() { doTest(); } + public void testNullWarningAfterInstanceofCheck() { doTest(); } } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java index a0a2518f8c54..387c034ce34f 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java @@ -1276,7 +1276,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { type = type.fromRelation(RelationType.EQ); for (DfaVariableValue value : eqClass.asList()) { if (value != dfaVar) { - recordVariableType(value, type); + recordVariableType(value, type.meet(value.getInherentType())); if (!updateQualifierOnEquality(value, value)) return false; } }