diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfDoubleRangeType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfDoubleRangeType.java
index 4988b7b13f34..d607ad226b4c 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfDoubleRangeType.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfDoubleRangeType.java
@@ -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);
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfFloatRangeType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfFloatRangeType.java
index 0816d030dffe..4c57e9e51fbb 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfFloatRangeType.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfFloatRangeType.java
@@ -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);
}
}
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FloatingPointRanges.java b/java/java-tests/testData/inspection/dataFlow/fixture/FloatingPointRanges.java
index e5c20ab8f64e..3b81fdc0a06d 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/FloatingPointRanges.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FloatingPointRanges.java
@@ -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 (d > Double.POSITIVE_INFINITY) {}
if (d < Double.NEGATIVE_INFINITY) {}