mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 22:09:38 +07:00
Check array length > 0 on array access even if index is unknown
Fixes IDEA-246390 DFA skips the warning "Array index is out of bounds" in for-loop GitOrigin-RevId: 828e7353ad7220472818b10f4d4c51c5a8eeba64
This commit is contained in:
committed by
intellij-monorepo-bot
parent
477e161c7d
commit
ecb8fba035
@@ -164,19 +164,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
PsiArrayAccessExpression arrayExpression = instruction.getExpression();
|
||||
DfaValue index = memState.pop();
|
||||
DfaValue array = memState.pop();
|
||||
boolean alwaysOutOfBounds = false;
|
||||
DfaValueFactory factory = runner.getFactory();
|
||||
if (!DfaTypeValue.isUnknown(index)) {
|
||||
DfaCondition indexNonNegative = index.cond(RelationType.GE, factory.getInt(0));
|
||||
if (!memState.applyCondition(indexNonNegative)) {
|
||||
alwaysOutOfBounds = true;
|
||||
}
|
||||
DfaValue dfaLength = SpecialField.ARRAY_LENGTH.createValue(factory, array);
|
||||
DfaCondition indexLessThanLength = index.cond(RelationType.LT, dfaLength);
|
||||
if (!memState.applyCondition(indexLessThanLength)) {
|
||||
alwaysOutOfBounds = true;
|
||||
}
|
||||
}
|
||||
boolean alwaysOutOfBounds = !applyBoundsCheck(memState, array, index);
|
||||
processArrayAccess(arrayExpression, alwaysOutOfBounds);
|
||||
if (alwaysOutOfBounds) {
|
||||
DfaControlTransferValue transfer = instruction.getOutOfBoundsExceptionTransfer();
|
||||
@@ -207,6 +195,20 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
return nextInstruction(instruction, runner, memState);
|
||||
}
|
||||
|
||||
private static boolean applyBoundsCheck(@NotNull DfaMemoryState memState,
|
||||
@NotNull DfaValue array,
|
||||
@NotNull DfaValue index) {
|
||||
DfaValueFactory factory = index.getFactory();
|
||||
DfaValue length = SpecialField.ARRAY_LENGTH.createValue(factory, array);
|
||||
DfaCondition lengthMoreThanZero = length.cond(RelationType.GT, factory.getInt(0));
|
||||
if (!memState.applyCondition(lengthMoreThanZero)) return false;
|
||||
DfaCondition indexNonNegative = index.cond(RelationType.GE, factory.getInt(0));
|
||||
if (!memState.applyCondition(indexNonNegative)) return false;
|
||||
DfaCondition indexLessThanLength = index.cond(RelationType.LT, length);
|
||||
if (!memState.applyCondition(indexLessThanLength)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void processArrayAccess(PsiArrayAccessExpression expression, boolean alwaysOutOfBounds) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ArrayLength {
|
||||
void testArrayLengthNonZeroUnknownIndex(int[] arr, int a, int b, int c) {
|
||||
arr[a+b+c] = 0;
|
||||
if (<warning descr="Condition 'arr.length == 0' is always 'false'">arr.length == 0</warning>) {}
|
||||
}
|
||||
|
||||
public static void diff(String[] args, String[] args2) {
|
||||
String[] arr = new String[args2.length - args.length];
|
||||
if (arr.length > 0) {}
|
||||
|
||||
Reference in New Issue
Block a user