From dec53c8d6c5baca7db30a1c1e69acafd99b3e0ec Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Mon, 4 Apr 2016 16:21:06 +0300 Subject: [PATCH] Fix for KT-11762: "VerifyError: Bad local variable type" caused by explicit loop variable type #KT-11762 Fixed --- .../jetbrains/kotlin/codegen/ExpressionCodegen.java | 10 ++++++---- .../codegen/box/controlStructures/forArrayList.kt | 11 +++++++++++ .../box/controlStructures/forArrayListMultiDecl.kt | 12 ++++++++++++ .../kotlin/codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/box/controlStructures/forArrayList.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forArrayListMultiDecl.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index be3ff10f670..055a438ab4a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -635,6 +635,7 @@ public class ExpressionCodegen extends KtVisitor impleme protected final Type asmElementType; protected int loopParameterVar; + protected Type loopParameterType; private AbstractForLoopGenerator(@NotNull KtForExpression forExpression) { this.forExpression = forExpression; @@ -658,14 +659,14 @@ public class ExpressionCodegen extends KtVisitor impleme if (loopParameter != null) { // E e = tmp.next() final VariableDescriptor parameterDescriptor = bindingContext.get(VALUE_PARAMETER, loopParameter); - @SuppressWarnings("ConstantConditions") final Type asmTypeForParameter = asmType(parameterDescriptor.getType()); - loopParameterVar = myFrameMap.enter(parameterDescriptor, asmTypeForParameter); + loopParameterType = asmType(parameterDescriptor.getType()); + loopParameterVar = myFrameMap.enter(parameterDescriptor, loopParameterType); scheduleLeaveVariable(new Runnable() { @Override public void run() { myFrameMap.leave(parameterDescriptor); v.visitLocalVariable(parameterDescriptor.getName().asString(), - asmTypeForParameter.getDescriptor(), null, + loopParameterType.getDescriptor(), null, bodyStart, bodyEnd, loopParameterVar); } @@ -676,6 +677,7 @@ public class ExpressionCodegen extends KtVisitor impleme assert multiParameter != null; // E tmp = tmp.next() + loopParameterType = asmElementType; loopParameterVar = createLoopTempVariable(asmElementType); } } @@ -843,7 +845,7 @@ public class ExpressionCodegen extends KtVisitor impleme makeFakeCall(new TransientReceiver(iteratorCall.getResultingDescriptor().getReturnType())); StackValue value = invokeFunction(fakeCall, nextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator)); //noinspection ConstantConditions - StackValue.local(loopParameterVar, asmType(nextCall.getResultingDescriptor().getReturnType())).store(value, v); + StackValue.local(loopParameterVar, loopParameterType).store(value, v); } @Override diff --git a/compiler/testData/codegen/box/controlStructures/forArrayList.kt b/compiler/testData/codegen/box/controlStructures/forArrayList.kt new file mode 100644 index 00000000000..cce12773de3 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forArrayList.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME +val alist = arrayListOf(1, 2, 3) // : j.u.ArrayList + +fun box(): String { + var result = 0 + for (i: Int in alist) { + result += i + } + + return if (result == 6) "OK" else "fail: $result" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forArrayListMultiDecl.kt b/compiler/testData/codegen/box/controlStructures/forArrayListMultiDecl.kt new file mode 100644 index 00000000000..04bd627762e --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forArrayListMultiDecl.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +val alist = arrayListOf(1 to 2, 2 to 3, 3 to 4) + +fun box(): String { + var result = 0 + for ((i: Int, z: Int) in alist) { + + result += i + z + } + + return if (result == 15) "OK" else "fail: $result" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index fa794e91d74..16f0989f9ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -3517,6 +3517,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("forArrayList.kt") + public void testForArrayList() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forArrayList.kt"); + doTest(fileName); + } + + @TestMetadata("forArrayListMultiDecl.kt") + public void testForArrayListMultiDecl() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forArrayListMultiDecl.kt"); + doTest(fileName); + } + @TestMetadata("forInSmartCastToArray.kt") public void testForInSmartCastToArray() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInSmartCastToArray.kt");