Fix for KT-12582: "VerifyError: Bad local variable type" caused by explicit loop variable type
#KT-12582 Fixed
This commit is contained in:
@@ -766,9 +766,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
// This method consumes range/progression from stack
|
// This method consumes range/progression from stack
|
||||||
// The result is stored to local variable
|
// The result is stored to local variable
|
||||||
protected void generateRangeOrProgressionProperty(Type loopRangeType, String getterName, Type elementType, int varToStore) {
|
protected void generateRangeOrProgressionProperty(
|
||||||
v.invokevirtual(loopRangeType.getInternalName(), getterName, "()" + elementType.getDescriptor(), false);
|
@NotNull Type loopRangeType,
|
||||||
v.store(varToStore, elementType);
|
@NotNull String getterName,
|
||||||
|
@NotNull Type getterReturnType,
|
||||||
|
@NotNull Type varType,
|
||||||
|
int varToStore
|
||||||
|
) {
|
||||||
|
v.invokevirtual(loopRangeType.getInternalName(), getterName, "()" + getterReturnType.getDescriptor(), false);
|
||||||
|
StackValue.local(varToStore, varType).store(StackValue.onStack(getterReturnType), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,6 +929,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
private abstract class AbstractForInProgressionOrRangeLoopGenerator extends AbstractForLoopGenerator {
|
private abstract class AbstractForInProgressionOrRangeLoopGenerator extends AbstractForLoopGenerator {
|
||||||
protected int endVar;
|
protected int endVar;
|
||||||
|
|
||||||
|
private StackValue loopParameter;
|
||||||
|
|
||||||
private AbstractForInProgressionOrRangeLoopGenerator(@NotNull KtForExpression forExpression) {
|
private AbstractForInProgressionOrRangeLoopGenerator(@NotNull KtForExpression forExpression) {
|
||||||
super(forExpression);
|
super(forExpression);
|
||||||
|
|
||||||
@@ -949,8 +957,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
protected void checkPostCondition(@NotNull Label loopExit) {
|
protected void checkPostCondition(@NotNull Label loopExit) {
|
||||||
assert endVar != -1 :
|
assert endVar != -1 :
|
||||||
"endVar must be allocated, endVar = " + endVar;
|
"endVar must be allocated, endVar = " + endVar;
|
||||||
|
loopParameter().put(asmElementType, v);
|
||||||
v.load(loopParameterVar, asmElementType);
|
|
||||||
v.load(endVar, asmElementType);
|
v.load(endVar, asmElementType);
|
||||||
if (asmElementType.getSort() == Type.LONG) {
|
if (asmElementType.getSort() == Type.LONG) {
|
||||||
v.lcmp();
|
v.lcmp();
|
||||||
@@ -964,6 +971,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
@Override
|
@Override
|
||||||
public void checkPreCondition(@NotNull Label loopExit) {
|
public void checkPreCondition(@NotNull Label loopExit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected StackValue loopParameter() {
|
||||||
|
if (loopParameter == null) {
|
||||||
|
loopParameter = StackValue.local(loopParameterVar, loopParameterType);
|
||||||
|
}
|
||||||
|
return loopParameter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class AbstractForInRangeLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator {
|
private abstract class AbstractForInRangeLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator {
|
||||||
@@ -982,8 +997,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||||
|
loopParameter().put(asmElementType, v);
|
||||||
v.load(loopParameterVar, asmElementType);
|
|
||||||
v.load(endVar, asmElementType);
|
v.load(endVar, asmElementType);
|
||||||
if (asmElementType.getSort() == Type.LONG) {
|
if (asmElementType.getSort() == Type.LONG) {
|
||||||
v.lcmp();
|
v.lcmp();
|
||||||
@@ -1002,13 +1016,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
protected void increment(@NotNull Label loopExit) {
|
protected void increment(@NotNull Label loopExit) {
|
||||||
checkPostCondition(loopExit);
|
checkPostCondition(loopExit);
|
||||||
|
|
||||||
if (asmElementType == Type.INT_TYPE) {
|
if (loopParameterType == Type.INT_TYPE) {
|
||||||
v.iinc(loopParameterVar, 1);
|
v.iinc(loopParameterVar, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.load(loopParameterVar, asmElementType);
|
StackValue loopParameter = loopParameter();
|
||||||
|
loopParameter.put(asmElementType, v);
|
||||||
genIncrement(asmElementType, 1, v);
|
genIncrement(asmElementType, 1, v);
|
||||||
v.store(loopParameterVar, asmElementType);
|
loopParameter.store(StackValue.onStack(asmElementType), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1026,8 +1041,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void storeRangeStartAndEnd() {
|
protected void storeRangeStartAndEnd() {
|
||||||
gen(rangeCall.left, asmElementType);
|
gen(rangeCall.left, loopParameterType);
|
||||||
v.store(loopParameterVar, asmElementType);
|
v.store(loopParameterVar, loopParameterType);
|
||||||
|
|
||||||
gen(rangeCall.right, asmElementType);
|
gen(rangeCall.right, asmElementType);
|
||||||
v.store(endVar, asmElementType);
|
v.store(endVar, asmElementType);
|
||||||
@@ -1048,8 +1063,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
// ranges inherit first and last from corresponding progressions
|
// ranges inherit first and last from corresponding progressions
|
||||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,15 +1095,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.dup();
|
v.dup();
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementVar);
|
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementType, incrementVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||||
|
loopParameter().put(asmElementType, v);
|
||||||
v.load(loopParameterVar, asmElementType);
|
|
||||||
v.load(endVar, asmElementType);
|
v.load(endVar, asmElementType);
|
||||||
v.load(incrementVar, incrementType);
|
v.load(incrementVar, incrementType);
|
||||||
|
|
||||||
@@ -1133,7 +1147,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
protected void increment(@NotNull Label loopExit) {
|
protected void increment(@NotNull Label loopExit) {
|
||||||
checkPostCondition(loopExit);
|
checkPostCondition(loopExit);
|
||||||
|
|
||||||
v.load(loopParameterVar, asmElementType);
|
StackValue loopParameter = loopParameter();
|
||||||
|
loopParameter.put(asmElementType, v);
|
||||||
v.load(incrementVar, asmElementType);
|
v.load(incrementVar, asmElementType);
|
||||||
v.add(asmElementType);
|
v.add(asmElementType);
|
||||||
|
|
||||||
@@ -1141,7 +1156,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
StackValue.coerce(Type.INT_TYPE, asmElementType, v);
|
StackValue.coerce(Type.INT_TYPE, asmElementType, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.store(loopParameterVar, asmElementType);
|
loopParameter.store(StackValue.onStack(asmElementType), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var result = 0
|
||||||
|
val intRange: IntProgression = 1..3
|
||||||
|
for (i: Int? in intRange) {
|
||||||
|
result = sum(result, i)
|
||||||
|
}
|
||||||
|
return if (result == 6) "OK" else "fail: $result"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sum(i: Int, z: Int?): Int {
|
||||||
|
return i + z!!
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var result = 0
|
||||||
|
val intRange = 1..3
|
||||||
|
for (i: Int? in intRange) {
|
||||||
|
result = sum(result, i)
|
||||||
|
}
|
||||||
|
return if (result == 6) "OK" else "fail: $result"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sum(i: Int, z: Int?): Int {
|
||||||
|
return i + z!!
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var result = 0
|
||||||
|
for (i: Int? in 1..3) {
|
||||||
|
result = sum(result, i)
|
||||||
|
}
|
||||||
|
return if (result == 6) "OK" else "fail: $result"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sum(i: Int, z: Int?): Int {
|
||||||
|
return i + z!!
|
||||||
|
}
|
||||||
@@ -10668,6 +10668,33 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/ranges/nullableLoopParameter")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NullableLoopParameter extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInNullableLoopParameter() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/nullableLoopParameter"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("progressionExpression.kt")
|
||||||
|
public void testProgressionExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/nullableLoopParameter/progressionExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("rangeExpression.kt")
|
||||||
|
public void testRangeExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/nullableLoopParameter/rangeExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("rangeLiteral.kt")
|
||||||
|
public void testRangeLiteral() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/nullableLoopParameter/rangeLiteral.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection")
|
@TestMetadata("compiler/testData/codegen/box/reflection")
|
||||||
|
|||||||
Reference in New Issue
Block a user