summaryrefslogtreecommitdiff
path: root/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java')
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java77
1 files changed, 52 insertions, 25 deletions
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 522bd34a9cf7..013e24cbe07a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -455,10 +455,10 @@ public class StandardInstructionVisitor extends InstructionVisitor {
DfaValue dfaRight,
DfaValue dfaLeft, IElementType opSign) {
if (dfaRight instanceof DfaConstValue && dfaLeft instanceof DfaVariableValue) {
- PsiType varType = ((DfaVariableValue)dfaLeft).getVariableType();
Object value = ((DfaConstValue)dfaRight).getValue();
- if (varType instanceof PsiPrimitiveType && value instanceof Number) {
- DfaInstructionState[] result = checkTypeRanges(instruction, runner, memState, opSign, varType, ((Number)value).longValue());
+ if (value instanceof Number) {
+ DfaInstructionState[] result = checkComparingWithConstant(instruction, runner, memState, (DfaVariableValue)dfaLeft, opSign,
+ ((Number)value).doubleValue());
if (result != null) {
return result;
}
@@ -485,33 +485,60 @@ public class StandardInstructionVisitor extends InstructionVisitor {
return null;
}
- private static DfaInstructionState[] checkTypeRanges(BinopInstruction instruction,
- DataFlowRunner runner,
- DfaMemoryState memState,
- IElementType opSign, PsiType varType, long constantValue) {
- long minValue = varType == PsiType.BYTE ? Byte.MIN_VALUE :
- varType == PsiType.SHORT ? Short.MIN_VALUE :
- varType == PsiType.INT ? Integer.MIN_VALUE :
- varType == PsiType.CHAR ? Character.MIN_VALUE :
- Long.MIN_VALUE;
- long maxValue = varType == PsiType.BYTE ? Byte.MAX_VALUE :
- varType == PsiType.SHORT ? Short.MAX_VALUE :
- varType == PsiType.INT ? Integer.MAX_VALUE :
- varType == PsiType.CHAR ? Character.MAX_VALUE :
- Long.MAX_VALUE;
-
- if (constantValue < minValue || constantValue > maxValue) {
+ @Nullable
+ private static DfaInstructionState[] checkComparingWithConstant(BinopInstruction instruction,
+ DataFlowRunner runner,
+ DfaMemoryState memState,
+ DfaVariableValue var,
+ IElementType opSign, double comparedWith) {
+ DfaConstValue knownConstantValue = memState.getConstantValue(var);
+ Object knownValue = knownConstantValue == null ? null : knownConstantValue.getValue();
+ if (knownValue instanceof Number) {
+ double knownDouble = ((Number)knownValue).doubleValue();
+ return checkComparisonWithKnownRange(instruction, runner, memState, opSign, comparedWith, knownDouble, knownDouble);
+ }
+
+ PsiType varType = var.getVariableType();
+ if (!(varType instanceof PsiPrimitiveType)) return null;
+
+ double minValue = varType == PsiType.BYTE ? Byte.MIN_VALUE :
+ varType == PsiType.SHORT ? Short.MIN_VALUE :
+ varType == PsiType.INT ? Integer.MIN_VALUE :
+ varType == PsiType.CHAR ? Character.MIN_VALUE :
+ varType == PsiType.LONG ? Long.MIN_VALUE :
+ varType == PsiType.FLOAT ? Float.MIN_VALUE :
+ Double.MIN_VALUE;
+ double maxValue = varType == PsiType.BYTE ? Byte.MAX_VALUE :
+ varType == PsiType.SHORT ? Short.MAX_VALUE :
+ varType == PsiType.INT ? Integer.MAX_VALUE :
+ varType == PsiType.CHAR ? Character.MAX_VALUE :
+ varType == PsiType.LONG ? Long.MAX_VALUE :
+ varType == PsiType.FLOAT ? Float.MAX_VALUE :
+ Double.MAX_VALUE;
+
+ return checkComparisonWithKnownRange(instruction, runner, memState, opSign, comparedWith, minValue, maxValue);
+ }
+
+ @Nullable
+ private static DfaInstructionState[] checkComparisonWithKnownRange(BinopInstruction instruction,
+ DataFlowRunner runner,
+ DfaMemoryState memState,
+ IElementType opSign,
+ double comparedWith,
+ double rangeMin,
+ double rangeMax) {
+ if (comparedWith < rangeMin || comparedWith > rangeMax) {
if (opSign == EQEQ) return alwaysFalse(instruction, runner, memState);
if (opSign == NE) return alwaysTrue(instruction, runner, memState);
}
- if (opSign == LT && constantValue <= minValue) return alwaysFalse(instruction, runner, memState);
- if (opSign == LT && constantValue > maxValue) return alwaysTrue(instruction, runner, memState);
- if (opSign == LE && constantValue >= maxValue) return alwaysTrue(instruction, runner, memState);
+ if (opSign == LT && comparedWith <= rangeMin) return alwaysFalse(instruction, runner, memState);
+ if (opSign == LT && comparedWith > rangeMax) return alwaysTrue(instruction, runner, memState);
+ if (opSign == LE && comparedWith >= rangeMax) return alwaysTrue(instruction, runner, memState);
- if (opSign == GT && constantValue >= maxValue) return alwaysFalse(instruction, runner, memState);
- if (opSign == GT && constantValue < minValue) return alwaysTrue(instruction, runner, memState);
- if (opSign == GE && constantValue <= minValue) return alwaysTrue(instruction, runner, memState);
+ if (opSign == GT && comparedWith >= rangeMax) return alwaysFalse(instruction, runner, memState);
+ if (opSign == GT && comparedWith < rangeMin) return alwaysTrue(instruction, runner, memState);
+ if (opSign == GE && comparedWith <= rangeMin) return alwaysTrue(instruction, runner, memState);
return null;
}