mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] Visit catch(AIOOBE) block in case if array access can be successful
GitOrigin-RevId: 49249d1a34b1b29b709bdb76e367ab3c705a05ef
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0237abc6f4
commit
4a2a326a25
+8
-2
@@ -5,8 +5,8 @@ import com.intellij.codeInspection.dataFlow.TypeConstraint;
|
||||
import com.intellij.codeInspection.dataFlow.interpreter.DataFlowInterpreter;
|
||||
import com.intellij.codeInspection.dataFlow.java.JavaDfaHelpers;
|
||||
import com.intellij.codeInspection.dataFlow.jvm.descriptors.ArrayElementDescriptor;
|
||||
import com.intellij.codeInspection.dataFlow.lang.DfaAnchor;
|
||||
import com.intellij.codeInspection.dataFlow.jvm.problems.IndexOutOfBoundsProblem;
|
||||
import com.intellij.codeInspection.dataFlow.lang.DfaAnchor;
|
||||
import com.intellij.codeInspection.dataFlow.lang.ir.DfaInstructionState;
|
||||
import com.intellij.codeInspection.dataFlow.lang.ir.ExpressionPushingInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.lang.ir.Instruction;
|
||||
@@ -19,6 +19,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayAccessInstruction extends ExpressionPushingInstruction {
|
||||
@@ -47,6 +48,10 @@ public class ArrayAccessInstruction extends ExpressionPushingInstruction {
|
||||
public DfaInstructionState[] accept(@NotNull DataFlowInterpreter interpreter, @NotNull DfaMemoryState stateBefore) {
|
||||
DfaValue index = stateBefore.pop();
|
||||
DfaValue array = stateBefore.pop();
|
||||
List<DfaInstructionState> finalStates = new ArrayList<>();
|
||||
if (myOutOfBoundsTransfer != null) {
|
||||
finalStates.addAll(IndexOutOfBoundsProblem.dispatchTransfer(interpreter, stateBefore, myOutOfBoundsTransfer));
|
||||
}
|
||||
DfaInstructionState[] states = myProblem.processOutOfBounds(interpreter, stateBefore, index, array, myOutOfBoundsTransfer);
|
||||
if (states != null) return states;
|
||||
LongRangeSet rangeSet = DfIntType.extractRange(stateBefore.getDfType(index));
|
||||
@@ -68,7 +73,8 @@ public class ArrayAccessInstruction extends ExpressionPushingInstruction {
|
||||
}
|
||||
}
|
||||
pushResult(interpreter, stateBefore, result);
|
||||
return nextStates(interpreter, stateBefore);
|
||||
finalStates.add(nextState(interpreter, stateBefore));
|
||||
return finalStates.toArray(DfaInstructionState.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-1
@@ -20,6 +20,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -53,6 +54,10 @@ public class ArrayStoreInstruction extends ExpressionPushingInstruction {
|
||||
DfaValue valueToStore = stateBefore.pop();
|
||||
DfaValue index = stateBefore.pop();
|
||||
DfaValue array = stateBefore.pop();
|
||||
List<DfaInstructionState> finalStates = new ArrayList<>();
|
||||
if (myOutOfBoundsTransfer != null) {
|
||||
finalStates.addAll(IndexOutOfBoundsProblem.dispatchTransfer(interpreter, stateBefore, myOutOfBoundsTransfer));
|
||||
}
|
||||
DfaInstructionState[] states =
|
||||
myIndexProblem.processOutOfBounds(interpreter, stateBefore, index, array, myOutOfBoundsTransfer);
|
||||
if (states != null) return states;
|
||||
@@ -71,7 +76,8 @@ public class ArrayStoreInstruction extends ExpressionPushingInstruction {
|
||||
stateBefore.flushFieldsQualifiedBy(Set.of(array));
|
||||
pushResult(interpreter, stateBefore, valueToStore);
|
||||
}
|
||||
return nextStates(interpreter, stateBefore);
|
||||
finalStates.add(nextState(interpreter, stateBefore));
|
||||
return finalStates.toArray(DfaInstructionState.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
protected void checkArrayElementAssignability(@NotNull DataFlowInterpreter interpreter,
|
||||
|
||||
+11
-4
@@ -45,14 +45,21 @@ public interface IndexOutOfBoundsProblem extends UnsatisfiedConditionProblem {
|
||||
interpreter.getListener().onCondition(this, index, failed, stateBefore);
|
||||
if (alwaysOutOfBounds) {
|
||||
if (outOfBoundsTransfer != null) {
|
||||
List<DfaInstructionState> states = outOfBoundsTransfer.dispatch(stateBefore, interpreter);
|
||||
for (DfaInstructionState state : states) {
|
||||
state.getMemoryState().markEphemeral();
|
||||
}
|
||||
List<DfaInstructionState> states = dispatchTransfer(interpreter, stateBefore, outOfBoundsTransfer);
|
||||
return states.toArray(DfaInstructionState.EMPTY_ARRAY);
|
||||
}
|
||||
return DfaInstructionState.EMPTY_ARRAY;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static @NotNull List<DfaInstructionState> dispatchTransfer(@NotNull DataFlowInterpreter interpreter,
|
||||
@NotNull DfaMemoryState stateBefore,
|
||||
@NotNull DfaControlTransferValue outOfBoundsTransfer) {
|
||||
List<DfaInstructionState> states = outOfBoundsTransfer.dispatch(stateBefore, interpreter);
|
||||
for (DfaInstructionState state : states) {
|
||||
state.getMemoryState().markEphemeral();
|
||||
}
|
||||
return states;
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
class Test {
|
||||
static final int[] DATA = {1, 2, 3};
|
||||
|
||||
int test(int value) {
|
||||
try {
|
||||
return DATA[value];
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void test2(int value) {
|
||||
try {
|
||||
DATA[value] = -1;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -45,6 +45,8 @@ public class UnreachableCodeInspectionTest extends LightJavaCodeInsightFixtureTe
|
||||
public void testUnresolvedCast() { doTest(); }
|
||||
|
||||
public void testUnresolvedCall() { doTest(); }
|
||||
|
||||
public void testArrayIndexOutOfBounds() { doTest(); }
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
Reference in New Issue
Block a user