[java-dfa] Properly meet two inverted ranges when excluded parts don't intersect

Fixes IDEA-275487 Incorrect warning when using consecutive expressions to determine the unordered numbers

GitOrigin-RevId: 14c0dd4e81b7b399ff5e5aac7dd036312ea8d9ad
This commit is contained in:
Tagir Valeev
2021-08-10 00:20:50 +00:00
committed by intellij-monorepo-bot
parent 293afecad8
commit 7e678abdaf
3 changed files with 30 additions and 6 deletions
@@ -172,9 +172,19 @@ class DfDoubleRangeType implements DfDoubleType {
if (!range.myInvert) {
return range.meet(this);
} else {
double from = Math.min(myFrom, range.myFrom);
double to = Math.max(myTo, range.myTo);
return create(from, to, true, nan);
// both inverted
if (myTo >= Math.nextDown(range.myFrom) && range.myTo >= Math.nextDown(myFrom)) {
// excluded ranges intersect or touch each other: we can exclude their union
double from = Math.min(myFrom, range.myFrom);
double to = Math.max(myTo, range.myTo);
return create(from, to, true, nan);
}
// excluded ranges don't intersect: we cannot encode this case
// just keep one of the ranges (with lesser from, for stability)
if (myFrom < range.myFrom) {
return create(myFrom, myTo, true, nan);
}
return create(range.myFrom, range.myTo, true, nan);
}
}
}
@@ -172,9 +172,19 @@ class DfFloatRangeType implements DfFloatType {
if (!range.myInvert) {
return range.meet(this);
} else {
float from = Math.min(myFrom, range.myFrom);
float to = Math.max(myTo, range.myTo);
return create(from, to, true, nan);
// both inverted
if (myTo >= Math.nextDown(range.myFrom) && range.myTo >= Math.nextDown(myFrom)) {
// excluded ranges intersect or touch each other: we can exclude their union
float from = Math.min(myFrom, range.myFrom);
float to = Math.max(myTo, range.myTo);
return create(from, to, true, nan);
}
// excluded ranges don't intersect: we cannot encode this case
// just keep one of the ranges (with lesser from, for stability)
if (myFrom < range.myFrom) {
return create(myFrom, myTo, true, nan);
}
return create(range.myFrom, range.myTo, true, nan);
}
}
}
@@ -1,6 +1,10 @@
import java.util.*;
public class FloatingPointRanges {
public static boolean isSpecial(double value) {
return value == 1.0 || value == -1.0 || value == 0.0;
}
void testSimple(double d) {
if (<warning descr="Condition 'd > Double.POSITIVE_INFINITY' is always 'false'">d > Double.POSITIVE_INFINITY</warning>) {}
if (<warning descr="Condition 'd < Double.NEGATIVE_INFINITY' is always 'false'">d < Double.NEGATIVE_INFINITY</warning>) {}