mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DfaMemoryStateImpl#removeEquivalenceRelations: restore class invariant on every iteration
Invariant is required for convertQualifiers to function properly Fixes EA-127085 - NPE: DfaMemoryStateImpl.getEqClassIndex
This commit is contained in:
+14
-15
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 || <error descr="Operator '<' cannot be applied to 'int', 'int[]'">numInArr < arr</error><error descr="')' expected"><error descr="Unexpected token">[</error></error><error descr="Unexpected token">]</error><error descr="Unexpected token">)</error>
|
||||
|
||||
int divisorsCount = 0;
|
||||
for(int y=numInArr; y > 0; y--) {
|
||||
}
|
||||
|
||||
divisorsForAllNums[i] = new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -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(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user