ControlFlowAnalyzer: assign initialized array elements to unknown to drop locality if necessary

Fixes IDEA-210027 Variable in dataflow remains local when used inside array initializer
This commit is contained in:
Tagir Valeev
2019-04-02 11:24:34 +07:00
parent 90cfb46930
commit 4af91368ca
2 changed files with 19 additions and 6 deletions
@@ -1294,27 +1294,28 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
addInstruction(new AssignInstruction(originalExpression, arrayWriteTarget));
int index = 0;
for (PsiExpression initializer : initializers) {
DfaValue target = null;
if (index < MAX_ARRAY_INDEX_FOR_INITIALIZER) {
DfaValue target = Objects.requireNonNull(expressionFactory.getArrayElementValue(arrayWriteTarget, index));
addInstruction(new PushInstruction(target, null, true));
target = Objects.requireNonNull(expressionFactory.getArrayElementValue(arrayWriteTarget, index));
}
index++;
addInstruction(new PushInstruction(target, null, true));
initializer.accept(this);
if (componentType != null) {
generateBoxingUnboxingInstructionFor(initializer, componentType);
}
if (index < MAX_ARRAY_INDEX_FOR_INITIALIZER) {
addInstruction(new AssignInstruction(initializer, null));
}
index++;
addInstruction(new AssignInstruction(initializer, null));
addInstruction(new PopInstruction());
}
}
else {
for (PsiExpression initializer : initializers) {
addInstruction(new PushInstruction(null, null, true));
initializer.accept(this);
if (componentType != null) {
generateBoxingUnboxingInstructionFor(initializer, componentType);
}
addInstruction(new AssignInstruction(initializer, null));
addInstruction(new PopInstruction());
}
addInstruction(new PushInstruction(var, null, true));
@@ -218,4 +218,16 @@ class AdvancedArrayAccess {
if(<warning descr="Condition 'arr2[32] == 32' is always 'true'">arr2[32] == 32</warning>) {}
if(<warning descr="Condition 'arr2[33] == 33' is always 'true'">arr2[33] == 33</warning>) {}
}
private static void change(Object[] x) {
((String[]) x[0])[0] = "OK";
}
// IDEA-210027
public static void main(String[] args) {
String[] array = new String[] { null };
change(new Object[] { array });
System.out.println(array[0]); // <-- Value 'array[0]' is always 'null'
}
}