ControlFlowAnalyzer: add missing boxing on loop unrolling when necessary

This commit is contained in:
Tagir Valeev
2018-07-31 02:27:19 +07:00
parent 8bc1fda4d7
commit ad81bf2d4a
5 changed files with 12 additions and 7 deletions
@@ -721,7 +721,7 @@ public class CFGBuilder {
ConditionalGotoInstruction condGoto = new ConditionalGotoInstruction(null, false, null);
condGoto.setOffset(myAnalyzer.getInstructionCount());
myBranches.add(() -> pushUnknown().add(condGoto));
assign(targetVariable, factory.createCommonValue(expressions));
assign(targetVariable, factory.createCommonValue(expressions, targetVariable.getVariableType()));
} else {
push(factory.getConstFactory().getSentinel());
for (PsiExpression expression : expressions) {
@@ -485,7 +485,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(statement);
}
private DfaValue getIteratedElement(PsiExpression iteratedValue) {
private DfaValue getIteratedElement(PsiType type, PsiExpression iteratedValue) {
PsiExpression[] expressions = null;
if (iteratedValue instanceof PsiNewExpression) {
PsiArrayInitializerExpression initializer = ((PsiNewExpression)iteratedValue).getArrayInitializer();
@@ -502,7 +502,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (iteratedValue instanceof PsiMethodCallExpression && LIST_INITIALIZER.test((PsiMethodCallExpression)iteratedValue)) {
expressions = ((PsiMethodCallExpression)iteratedValue).getArgumentList().getExpressions();
}
return expressions == null ? DfaUnknownValue.getInstance() : getFactory().createCommonValue(expressions);
return expressions == null ? DfaUnknownValue.getInstance() : getFactory().createCommonValue(expressions, type);
}
@Override public void visitForeachStatement(PsiForeachStatement statement) {
@@ -539,7 +539,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
ControlFlowOffset offset = myCurrentFlow.getNextOffset();
DfaVariableValue dfaVariable = myFactory.getVarFactory().createVariableValue(parameter);
new CFGBuilder(this).assignAndPop(dfaVariable, getIteratedElement(iteratedValue));
new CFGBuilder(this).assignAndPop(dfaVariable, getIteratedElement(parameter.getType(), iteratedValue));
if (!hasSizeCheck) {
pushUnknown();
@@ -322,7 +322,7 @@ public class DfaExpressionFactory {
.orElse(DfaUnknownValue.getInstance());
}
private DfaValue boxUnbox(DfaValue value, PsiType type) {
DfaValue boxUnbox(DfaValue value, PsiType type) {
if (TypeConversionUtil.isPrimitiveWrapper(type)) {
if (value instanceof DfaConstValue || value instanceof DfaUnboxedValue ||
(value instanceof DfaVariableValue && TypeConversionUtil.isPrimitiveAndNotNull(((DfaVariableValue)value).getVariableType()))) {
@@ -262,7 +262,7 @@ public class DfaValueFactory {
public DfaExpressionFactory getExpressionFactory() { return myExpressionFactory;}
@NotNull
public DfaValue createCommonValue(@NotNull PsiExpression[] expressions) {
public DfaValue createCommonValue(@NotNull PsiExpression[] expressions, PsiType targetType) {
DfaValue loopElement = null;
for (PsiExpression expression : expressions) {
DfaValue expressionValue = createValue(expression);
@@ -272,7 +272,7 @@ public class DfaValueFactory {
loopElement = loopElement == null ? expressionValue : loopElement.union(expressionValue);
if (loopElement == DfaUnknownValue.getInstance()) break;
}
return loopElement == null ? DfaUnknownValue.getInstance() : loopElement;
return loopElement == null ? DfaUnknownValue.getInstance() : getExpressionFactory().boxUnbox(loopElement, targetType);
}
private static class ClassInitializationInfo {
@@ -26,4 +26,9 @@ class ForeachCollectionElement {
}
}
}
void test4() {
for(Integer x : Arrays.asList(1)) {
}
}
}