From f2f23f3610e71ad45a00b91226c4c69dc61adfa2 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 18 Jun 2018 17:15:21 +0700 Subject: [PATCH] LongRangeSet.RangeSet#plus: convert to simple range if number of sets exceeds 3 Fixes IDEA-193987 IDE freeze when turn on code inspection data flow for Java --- .../dataFlow/rangeSet/LongRangeSet.java | 3 +++ ...yAdditionsDoNotCauseExponentialBlowUp.java | 26 +++++++++++++++++++ .../DataFlowRangeAnalysisTest.java | 2 ++ 3 files changed, 31 insertions(+) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/ManyAdditionsDoNotCauseExponentialBlowUp.java 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 0ccf501b8465..d48a12c466cc 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 @@ -1256,6 +1256,9 @@ public abstract class LongRangeSet { @NotNull @Override public LongRangeSet plus(LongRangeSet other, boolean isLong) { + if (myRanges.length > 6) { + return range(min(), max()).plus(other, isLong); + } LongRangeSet result = empty(); for (int i = 0; i < myRanges.length; i += 2) { result = result.union(range(myRanges[i], myRanges[i + 1]).plus(other, isLong)); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ManyAdditionsDoNotCauseExponentialBlowUp.java b/java/java-tests/testData/inspection/dataFlow/fixture/ManyAdditionsDoNotCauseExponentialBlowUp.java new file mode 100644 index 000000000000..0a1c8286007b --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ManyAdditionsDoNotCauseExponentialBlowUp.java @@ -0,0 +1,26 @@ +import java.util.*; + +class Test { + native boolean get(); + + void test() { + int x = get() ? 0 : 1<<30; + x = x + (get() ? 0 : 1<<29); + x = x + (get() ? 0 : 1<<28); + x = x + (get() ? 0 : 1<<27); + x = x + (get() ? 0 : 1<<26); + x = x + (get() ? 0 : 1<<25); + x = x + (get() ? 0 : 1<<24); + x = x + (get() ? 0 : 1<<23); + x = x + (get() ? 0 : 1<<22); + x = x + (get() ? 0 : 1<<21); + x = x + (get() ? 0 : 1<<20); + x = x + (get() ? 0 : 1<<19); + x = x + (get() ? 0 : 1<<18); + x = x + (get() ? 0 : 1<<17); + + if (x < 0) { + System.out.println("Impossible"); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java index 269aea633089..d0f8c1f88b04 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java @@ -62,4 +62,6 @@ public class DataFlowRangeAnalysisTest extends DataFlowInspectionTestCase { public void testLongRangePlusMinus() { doTest(); } public void testFebruary31() { doTest(); } + + public void testManyAdditionsDoNotCauseExponentialBlowUp() { doTest(); } }