From ad22cd9a7473da2e37f14b7734352fdf29a91e92 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 21 Apr 2021 11:32:36 +0700 Subject: [PATCH] [java-dfa] Fix ephemeral states on comparison GitOrigin-RevId: cd7fde86062bcda7145dae7b98c661a64fbccb9d --- .../dataFlow/DfaMemoryStateImpl.java | 14 +++++++------- .../fixture/UnknownComparedToNullable.java | 12 ++++++++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/UnknownComparedToNullable.java 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 e18fef1709fe..aa2adf53a4af 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 @@ -715,6 +715,11 @@ public class DfaMemoryStateImpl implements DfaMemoryState { if (DfaTypeValue.isUnknown(dfaLeft) || DfaTypeValue.isUnknown(dfaRight)) return true; + if (relationType == RelationType.EQ && dfaLeft instanceof DfaVariableValue && dfaRight instanceof DfaVariableValue) { + checkEphemeral(dfaLeft, dfaRight); + checkEphemeral(dfaRight, dfaLeft); + } + DfType leftType = getDfType(dfaLeft); DfType rightType = getDfType(dfaRight); @@ -877,13 +882,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return true; } - if (type == RelationType.EQ) { - if (dfaLeft instanceof DfaVariableValue && dfaRight instanceof DfaVariableValue) { - checkEphemeral(dfaLeft, dfaRight); - checkEphemeral(dfaRight, dfaLeft); - } - if (!applySpecialFieldEquivalence(dfaLeft, dfaRight)) return false; - } + if (type == RelationType.EQ && !applySpecialFieldEquivalence(dfaLeft, dfaRight)) return false; + if (dfaLeft instanceof DfaVariableValue && dfaRight instanceof DfaVariableValue && !isNegated) { if (!equalizeTypesOnGetClass((DfaVariableValue)dfaLeft, (DfaVariableValue)dfaRight)) { return false; diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/UnknownComparedToNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/UnknownComparedToNullable.java new file mode 100644 index 000000000000..91d30f81a856 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/UnknownComparedToNullable.java @@ -0,0 +1,12 @@ +import java.util.Set; + +public class UnknownComparedToNullable { + native Object getObject(int x); + + void test(int val) { + Object s1 = val < 0 ? null : getObject(val * 2); + Object s2 = getObject(val); + if (s1 != s2) {} + System.out.println(s2.hashCode()); + } +} \ 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 50a9171314ce..29d94fcfa3fc 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -696,4 +696,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testCollectionViewsSize() { doTest(); } public void testFlushedNullableOnUnknownCall() { doTest(); } public void testBoxedDivisionComparison() { doTest(); } + public void testUnknownComparedToNullable() { doTest(); } }