diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index 8e3ea68d75f7..396e41ff5991 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -320,18 +320,16 @@ public class DfaMemoryStateImpl implements DfaMemoryState { if (classes != null) { int i = ArrayUtil.indexOf(classes, index); if (i != -1) { - classes = ArrayUtil.remove(classes, i); - myIdToEqClassesIndices.put(id, classes); + if (classes.length == 1) { + myIdToEqClassesIndices.remove(id); + } else { + classes = ArrayUtil.remove(classes, i); + myIdToEqClassesIndices.put(id, classes); + } } } } - private void removeAllFromMap(int id) { - if (id < 0) return; - id = unwrap(myFactory.getValue(id)).getID(); - myIdToEqClassesIndices.remove(id); - } - /** * Returns true if current state describes all possible concrete program states described by {@code that} state. * @@ -1374,14 +1372,15 @@ public class DfaMemoryStateImpl implements DfaMemoryState { myCachedHash = null; } - void removeEquivalenceRelations(@NotNull DfaVariableValue varPlain) { - final int idPlain = varPlain.getID(); + void removeEquivalenceRelations(@NotNull DfaVariableValue var) { + final int varID = var.getID(); - int[] result = ObjectUtils.notNull(myIdToEqClassesIndices.get(idPlain), ArrayUtil.EMPTY_INT_ARRAY); + int[] classes = myIdToEqClassesIndices.get(varID); + if (classes == null) return; int interruptCount = 0; - for (int varClassIndex : result) { + for (int varClassIndex : classes) { EqClass varClass = myEqClasses.get(varClassIndex); if ((++interruptCount & 0xf) == 0) { ProgressManager.checkCanceled(); @@ -1391,7 +1390,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { DfaVariableValue previousCanonical = varClass.getCanonicalVariable(); myEqClasses.set(varClassIndex, varClass); for (int id : varClass.toNativeArray()) { - if (id == idPlain || unwrap(myFactory.getValue(id)).getID() == idPlain) { + if (id == varID || unwrap(myFactory.getValue(id)).getID() == varID) { varClass.removeValue(id); } } @@ -1425,10 +1424,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState { assert successfullyConverted; } } + removeFromMap(varID, varClassIndex); + checkInvariants(); } - removeAllFromMap(idPlain); - checkInvariants(); myCachedNonTrivialEqClasses = null; myCachedHash = null; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteArrayAccessInLoop.java b/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteArrayAccessInLoop.java new file mode 100644 index 000000000000..d870018294a7 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteArrayAccessInLoop.java @@ -0,0 +1,15 @@ +class X { + void test(int[] arr, int[][] divisorsForAllNums) { + for(int i=0; i < arr.length; i++) { + int numInArr = arr[i]; + + if(i == 0 || numInArr < arr[]) + + int divisorsCount = 0; + for(int y=numInArr; y > 0; y--) { + } + + divisorsForAllNums[i] = new int[0]; + } + } +} \ 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 83ad212215c1..1b55d99b8390 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -28,6 +28,8 @@ import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + /** * @author peter */ @@ -564,12 +566,12 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { @Override public boolean isImplicitlyNotNullInitialized(@NotNull PsiElement element) { - return element instanceof PsiField && ((PsiField)element).getName().startsWith("field"); + return element instanceof PsiField && ((PsiField)element).getName() != null && ((PsiField)element).getName().startsWith("field"); } @Override public boolean isClassWithCustomizedInitialization(@NotNull PsiElement element) { - return element instanceof PsiClass && ((PsiClass)element).getName().equals("Instrumented"); + return element instanceof PsiClass && Objects.equals(((PsiClass)element).getName(), "Instrumented"); } }, myFixture.getTestRootDisposable()); doTest(); @@ -641,4 +643,6 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testAssignmentFieldAliasing() { doTest(); } public void testNewBoxedNumberEquality() { doTest(); } public void testBoxingIncorrectLiteral() { doTest(); } + + public void testIncompleteArrayAccessInLoop() { doTest(); } }