From 14d6ae1b03ff7b8ddabd7057e09ec1a1528a3f37 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 25 Feb 2021 12:42:52 +0700 Subject: [PATCH] [java-dfa] Remove incorrect range-narrowing in ModRange.plus If we overflow and myMod is not a power of 2, we cannot rotate remainders: overflowed subrange may have different remainders. E.g. floorMod(Integer.MAX_VALUE, 6) = 1 but floorMod(Integer.MAX_VALUE+1, 6) = 4, not 2. Better algorithm is possible if we initially split our range at overflow point, then perform addition separately but for now let's just produce a correct result Fixes EA-257681 - IAE: LongRangeSet$Range. GitOrigin-RevId: 45a3a870ae238800386b6ce739694f8f847e6340 --- .../codeInspection/dataFlow/rangeSet/LongRangeSet.java | 6 +----- .../inspection/dataFlow/fixture/LongRangeMod.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java index 8e6cda216a1e..9f5f8703d634 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java @@ -1867,11 +1867,7 @@ public abstract class LongRangeSet { plus = modRange(ranges[i], ranges[i + 1], myMod, bits); } else { - long min = ranges[i]; - while (!isSet(bits, remainder(min, myMod))) min++; - long max = ranges[i + 1]; - while (!isSet(bits, remainder(max, myMod))) max--; - plus = range(min, max); + plus = range(ranges[i], ranges[i + 1]); } result = result.unite(plus); } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeMod.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeMod.java index 37a5224b82de..3ad4a445cb3e 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeMod.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeMod.java @@ -34,4 +34,14 @@ public class LongRangeMod { i++; } } + + // EA-257681 - IAE: LongRangeSet$Range. + void test(int a, int b) { + if (a % 2 == 0) + b += a / 2; + else if (a % 3 == 0) + b += a / 3; + else + a++; + } }