From 3457fe2b552abdd9edfb41bf6752c41495177e7c Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 11 Apr 2017 10:29:15 +0700 Subject: [PATCH] IDEA-168715 Dead code inspection doesn't work in loop (Conservatively handle including bound) --- .../dataFlow/ControlFlowAnalyzer.java | 7 ++++- .../dataFlow/fixture/LongRangeLoop.java | 26 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) 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) {