[java-dfa] Do not rely on equivalence relation for floating point types

Fixes IDEA-339464 "Constant values" false positive for NaN

GitOrigin-RevId: a7b824f8d6ba0d6a8e4c9dd402ed6810a60e0066
This commit is contained in:
Tagir Valeev
2023-12-01 18:37:17 +00:00
committed by intellij-monorepo-bot
parent f23adba5b9
commit fa99f2dd20
3 changed files with 27 additions and 5 deletions
@@ -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;
}
}
@@ -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(); }
@@ -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) {