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 9d891cb159d9..438cd3945dfd 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 @@ -1235,7 +1235,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { if (toPush == null) { toPush = myFactory.getObjectType(expression.getType(), Nullability.UNKNOWN); } - addInstruction(new ArrayAccessInstruction(toPush, expression)); + DfaControlTransferValue transfer = + shouldHandleException() ? myFactory.controlTransfer(myExceptionCache.get("java.lang.ArrayIndexOutOfBoundsException"), myTrapStack) : null; + addInstruction(new ArrayAccessInstruction(toPush, expression, transfer)); addNullCheck(expression); finishElement(expression); } 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 b99f30add902..a1bf0bdbb11a 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 @@ -179,6 +179,14 @@ public class StandardInstructionVisitor extends InstructionVisitor { } processArrayAccess(arrayExpression, alwaysOutOfBounds); if (alwaysOutOfBounds) { + DfaControlTransferValue transfer = instruction.getOutOfBoundsExceptionTransfer(); + if (transfer != null) { + List states = transfer.dispatch(memState, runner); + for (DfaInstructionState state : states) { + state.getMemoryState().markEphemeral(); + } + return states.toArray(DfaInstructionState.EMPTY_ARRAY); + } return DfaInstructionState.EMPTY_ARRAY; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ArrayAccessInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ArrayAccessInstruction.java index 8b554a88f194..910a04226490 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ArrayAccessInstruction.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ArrayAccessInstruction.java @@ -15,22 +15,29 @@ */ package com.intellij.codeInspection.dataFlow.instructions; -import com.intellij.codeInspection.dataFlow.DataFlowRunner; -import com.intellij.codeInspection.dataFlow.DfaInstructionState; -import com.intellij.codeInspection.dataFlow.DfaMemoryState; -import com.intellij.codeInspection.dataFlow.InstructionVisitor; +import com.intellij.codeInspection.dataFlow.*; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.psi.PsiArrayAccessExpression; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; public class ArrayAccessInstruction extends ExpressionPushingInstruction { private final @NotNull DfaValue myValue; + private final @Nullable DfaControlTransferValue myTransferValue; - public ArrayAccessInstruction(@NotNull DfaValue value, @NotNull PsiArrayAccessExpression expression) { + public ArrayAccessInstruction(@NotNull DfaValue value, + @NotNull PsiArrayAccessExpression expression, + @Nullable DfaControlTransferValue transferValue) { super(expression); myValue = value; + myTransferValue = transferValue; + } + + @Nullable + public DfaControlTransferValue getOutOfBoundsExceptionTransfer() { + return myTransferValue; } @NotNull diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AIOOBETransfer.java b/java/java-tests/testData/inspection/dataFlow/fixture/AIOOBETransfer.java new file mode 100644 index 000000000000..b2f708e067f0 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/AIOOBETransfer.java @@ -0,0 +1,12 @@ +class X { + // IDEA-246054 + void test(int[] data) { + for (int i = -1; i < data.length; i++) { + try { + data[i] = 0; + } catch (ArrayIndexOutOfBoundsException ignored) { + + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index e55422829c88..b7fbb7793642 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -675,4 +675,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testDefaultConstructor() { doTest(); } public void testInstanceOfUnresolved() { doTest(); } public void testProtobufNotNullGetters() { doTest(); } + public void testAIOOBETransfer() { doTest(); } }