mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ControlFlowAnalyzer: repeat unboxing for every case label if necessary
Without this it was possible (at least on the incorrect code) that boxed and unboxed classes for the same value get united, which in turn caused repeating entry in DfaMemoryStateImpl#myIdToEqClassesIndices, which could cause NPE when performing successive flush for given variable. Now we throw directly at classes unification attempt to catch illegal state earlier Fixes EA-118152 - IAE: EqClass.$$$reportNull$$$
This commit is contained in:
+2
-1
@@ -899,6 +899,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
((PsiReferenceExpression)caseExpression).getQualifierExpression() == null) {
|
||||
|
||||
addInstruction(new PushInstruction(myFactory.createValue(caseExpression), caseExpression));
|
||||
generateBoxingUnboxingInstructionFor(caseExpression, PsiType.INT);
|
||||
caseValue.accept(this);
|
||||
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, PsiType.BOOLEAN));
|
||||
}
|
||||
@@ -2066,7 +2067,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
private static final class Synthetic implements DfaVariableSource {
|
||||
private final int myLocation;
|
||||
|
||||
public Synthetic(int location) {
|
||||
private Synthetic(int location) {
|
||||
myLocation = location;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -344,6 +344,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
classes = new int[]{index};
|
||||
}
|
||||
else {
|
||||
if (ArrayUtil.indexOf(classes, index) != -1) {
|
||||
throw new IllegalStateException("Class index already referenced from the value: "+
|
||||
myEqClasses.get(index)+"; "+myFactory.getValue(id));
|
||||
}
|
||||
classes = ArrayUtil.append(classes, index);
|
||||
}
|
||||
myIdToEqClassesIndices.put(id, classes);
|
||||
|
||||
+2
-1
@@ -246,7 +246,8 @@ public class StreamChainInliner implements CallInliner {
|
||||
if (!(type instanceof PsiPrimitiveType)) {
|
||||
type = PsiPrimitiveType.getUnboxedType(type);
|
||||
}
|
||||
builder.push(builder.getFactory().getConstFactory().createDefault(Objects.requireNonNull(type)));
|
||||
builder.push(builder.getFactory().getConstFactory().createDefault(Objects.requireNonNull(type)))
|
||||
.boxUnbox(myCall, type, myCall.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
public enum Test {
|
||||
VALUE;
|
||||
|
||||
void test() {
|
||||
Integer code = getCode();
|
||||
switch (code) {
|
||||
case VALUE.value()<EOLError descr="':' expected"></EOLError>
|
||||
}
|
||||
if (code == VALUE.value()) {
|
||||
getCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int value() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public native Integer getCode();
|
||||
}
|
||||
@@ -96,6 +96,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
public void testNotEqualsDoesntImplyNotNullity() { doTest(); }
|
||||
public void testEqualsEnumConstant() { doTest(); }
|
||||
public void testSwitchEnumConstant() { doTest(); }
|
||||
public void testIncompleteSwitchEnum() { doTest(); }
|
||||
public void testEnumConstantNotNull() { doTest(); }
|
||||
public void testCheckEnumConstantConstructor() { doTest(); }
|
||||
public void testCompareToEnumConstant() { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user