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
|
||||
// The result is stored to local variable
|
||||
protected void generateRangeOrProgressionProperty(Type loopRangeType, String getterName, Type elementType, int varToStore) {
|
||||
v.invokevirtual(loopRangeType.getInternalName(), getterName, "()" + elementType.getDescriptor(), false);
|
||||
v.store(varToStore, elementType);
|
||||
protected void generateRangeOrProgressionProperty(
|
||||
@NotNull Type loopRangeType,
|
||||
@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 {
|
||||
protected int endVar;
|
||||
|
||||
private StackValue loopParameter;
|
||||
|
||||
private AbstractForInProgressionOrRangeLoopGenerator(@NotNull KtForExpression forExpression) {
|
||||
super(forExpression);
|
||||
|
||||
@@ -949,8 +957,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void checkPostCondition(@NotNull Label loopExit) {
|
||||
assert endVar != -1 :
|
||||
"endVar must be allocated, endVar = " + endVar;
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
if (asmElementType.getSort() == Type.LONG) {
|
||||
v.lcmp();
|
||||
@@ -964,6 +971,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@Override
|
||||
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 {
|
||||
@@ -982,8 +997,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
if (asmElementType.getSort() == Type.LONG) {
|
||||
v.lcmp();
|
||||
@@ -1002,13 +1016,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void increment(@NotNull Label loopExit) {
|
||||
checkPostCondition(loopExit);
|
||||
|
||||
if (asmElementType == Type.INT_TYPE) {
|
||||
if (loopParameterType == Type.INT_TYPE) {
|
||||
v.iinc(loopParameterVar, 1);
|
||||
}
|
||||
else {
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
StackValue loopParameter = loopParameter();
|
||||
loopParameter.put(asmElementType, 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
|
||||
protected void storeRangeStartAndEnd() {
|
||||
gen(rangeCall.left, asmElementType);
|
||||
v.store(loopParameterVar, asmElementType);
|
||||
gen(rangeCall.left, loopParameterType);
|
||||
v.store(loopParameterVar, loopParameterType);
|
||||
|
||||
gen(rangeCall.right, asmElementType);
|
||||
v.store(endVar, asmElementType);
|
||||
@@ -1048,8 +1063,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.dup();
|
||||
|
||||
// ranges inherit first and last from corresponding progressions
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,15 +1095,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.dup();
|
||||
v.dup();
|
||||
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementType, incrementVar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
v.load(incrementVar, incrementType);
|
||||
|
||||
@@ -1133,7 +1147,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void increment(@NotNull Label loopExit) {
|
||||
checkPostCondition(loopExit);
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
StackValue loopParameter = loopParameter();
|
||||
loopParameter.put(asmElementType, v);
|
||||
v.load(incrementVar, asmElementType);
|
||||
v.add(asmElementType);
|
||||
|
||||
@@ -1141,7 +1156,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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")
|
||||
|
||||
Reference in New Issue
Block a user