diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index bd05e8cb8da9..9407a57d5aec 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -514,8 +514,13 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
private void addCountingLoopBound(PsiForStatement statement) {
CountingLoop loop = CountingLoop.from(statement);
if (loop == null) return;
- // Add known-to-be-true condition inside counting loop, effectively converting
PsiLocalVariable counter = loop.getCounter();
+ if (loop.isIncluding() && !(PsiType.LONG.equals(counter.getType()) && PsiType.INT.equals(loop.getBound().getType()))) {
+ Object bound = ExpressionUtils.computeConstantExpression(loop.getBound());
+ // could be for(int i=0; i<=Integer.MAX_VALUE; i++) which will overflow: conservatively skip this
+ if (!(bound instanceof Number)) return;
+ if (bound.equals(Long.MAX_VALUE) || bound.equals(Integer.MAX_VALUE)) return;
+ }
PsiExpression initializer = loop.getInitializer();
if (!PsiType.INT.equals(initializer.getType()) && !PsiType.LONG.equals(initializer.getType())) return;
DfaValue origin = null;
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeLoop.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeLoop.java
index d37e6dd7d8e5..755042414fff 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeLoop.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeLoop.java
@@ -25,7 +25,7 @@ public class LongRangeLoop {
public static void loopOrigin(long i) {
if(i > 0) {
- for(long j = i; j < 1000; ++j) {
+ for (long j = i; j <= 1000; ++j) {
if (j < 0) {
System.out.println("Impossible");
}
@@ -33,6 +33,30 @@ public class LongRangeLoop {
}
}
+ public static void loopUnknownBoundIncluding(int bound) {
+ for (int i = 0; i <= bound; i++) {
+ if (i == -1) {
+ System.out.println("Overflow detected: bound was Integer.MAX_VALUE");
+ }
+ }
+ }
+
+ public static void loopUnknownBoundExcluding(int bound) {
+ for (int i = 0; i < bound; i++) {
+ if (i == -1) {
+ System.out.println("Impossible even if bound is Integer.MAX_VALUE");
+ }
+ }
+ }
+
+ public static void loopUnknownBoundIncludingLong(int bound) {
+ for (long i = 0; i <= bound; i++) {
+ if (i == -1) {
+ System.out.println("Impossible even if bound is Integer.MAX_VALUE");
+ }
+ }
+ }
+
public void IDEA168715() {
for (int i = 1; i < 100; i++) {
if (i == 0) {