From fa99f2dd20c6258f6252ad000074946df73a9af9 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 1 Dec 2023 17:16:59 +0100 Subject: [PATCH] [java-dfa] Do not rely on equivalence relation for floating point types Fixes IDEA-339464 "Constant values" false positive for NaN GitOrigin-RevId: a7b824f8d6ba0d6a8e4c9dd402ed6810a60e0066 --- .../dataFlow/fixture/DoubleNaN2.java | 19 +++++++++++++++++++ .../DataFlowInspectionTest.java | 1 + .../dataFlow/memory/DfaMemoryStateImpl.java | 12 +++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/DoubleNaN2.java diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/DoubleNaN2.java b/java/java-tests/testData/inspection/dataFlow/fixture/DoubleNaN2.java new file mode 100644 index 000000000000..6b843ac287b4 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/DoubleNaN2.java @@ -0,0 +1,19 @@ +public class DoubleNaN2 { + public static int compare(double lhs, double rhs) { + if (lhs == rhs) { + return 0; + } + if (lhs < rhs) { + return -1; + } + + if (lhs > rhs) { + return 1; + } + + if (Double.isNaN(lhs)) { + return Double.isNaN(rhs) ? 0 : -1; + } + return 1; + } +} \ 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 63c467bd774f..54c7a9edd52c 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -192,6 +192,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testMethodCallFlushesField() { doTest(); } public void testDoubleNaN() { doTest(); } + public void testDoubleNaN2() { doTest(); } public void testUnknownFloatMayBeNaN() { doTest(); } public void testBoxedNaN() { doTest(); } public void testFloatEquality() { 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 387c034ce34f..9aa1bb22f7da 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 @@ -1029,11 +1029,13 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } private boolean applyEquivalenceRelation(RelationType type, DfaValue dfaLeft, DfaValue dfaRight) { - RelationType currentRelation = getRelation(dfaLeft, dfaRight); - if (currentRelation != null) { - // Eq: NE & GE => GT - type = type.meet(currentRelation); - if (type == null) return false; + if (!dfaLeft.getDfType().hasNonStandardEquivalence() && !dfaRight.getDfType().hasNonStandardEquivalence()) { + RelationType currentRelation = getRelation(dfaLeft, dfaRight); + if (currentRelation != null) { + // Eq: NE & GE => GT + type = type.meet(currentRelation); + if (type == null) return false; + } } boolean isNegated = type == RelationType.NE || type == RelationType.GT || type == RelationType.LT; if (!isNegated && type != RelationType.EQ) {