From 21f2febf8282189a384a5893f297e686f7164dac Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 9 Nov 2016 13:40:20 +0100 Subject: [PATCH] Fix for KT-13557: VerifyError with delegated local variable used in object expression #KT-13557 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 4 ---- .../jetbrains/kotlin/codegen/JvmCodegenUtil.java | 5 +++++ .../kotlin/codegen/state/KotlinTypeMapper.java | 13 ++++++++++++- .../box/delegatedProperty/local/kt13557.kt | 15 +++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ 6 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index cec4ce8054c..336d05ac1dd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1937,10 +1937,6 @@ public class ExpressionCodegen extends KtVisitor impleme return asmType(varType); } - private static boolean isDelegatedLocalVariable(@NotNull DeclarationDescriptor descriptor) { - return descriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) descriptor).isDelegated(); - } - private static boolean isSharedVarType(@NotNull Type type) { return type.getSort() == Type.OBJECT && type.getInternalName().startsWith(REF_TYPE_PREFIX); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index 617fdcb5f5e..e3a45b2ac5e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.codegen.context.RootContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor; import org.jetbrains.kotlin.load.kotlin.*; import org.jetbrains.kotlin.psi.Call; @@ -303,4 +304,8 @@ public class JvmCodegenUtil { } return null; } + + public static boolean isDelegatedLocalVariable(@NotNull DeclarationDescriptor descriptor) { + return descriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) descriptor).isDelegated(); + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index be53feee31c..05a40722295 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor; import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.MutableClosure; +import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor; import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; @@ -80,6 +81,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.Collection; import java.util.List; +import java.util.Map; import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; @@ -1303,7 +1305,16 @@ public class KotlinTypeMapper { if (variableDescriptor instanceof VariableDescriptor && !(variableDescriptor instanceof PropertyDescriptor)) { Type sharedVarType = getSharedVarType(variableDescriptor); if (sharedVarType == null) { - sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType()); + if (isDelegatedLocalVariable(variableDescriptor)) { + VariableDescriptor delegateVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_DELEGATE, + (VariableDescriptor) variableDescriptor); + assert delegateVariableDescriptor != null : + "Local delegated property " + variableDescriptor + " delegate descriptor should be not null"; + sharedVarType = mapType(delegateVariableDescriptor.getType()); + } + else { + sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType()); + } } type = sharedVarType; } diff --git a/compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt b/compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt new file mode 100644 index 00000000000..bb765c93e1d --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt @@ -0,0 +1,15 @@ +//WITH_REFLECT + +import java.util.* +import kotlin.properties.Delegates + +fun box(): String { + var foo: String by Delegates.notNull(); + + object { + fun baz() { + foo = "OK" + } + }.baz() + return foo +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 3cba749bcf5..9d76fe37fb2 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5728,6 +5728,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt13557.kt") + public void testKt13557() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt"); + doTest(fileName); + } + @TestMetadata("localVal.kt") public void testLocalVal() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 950d198811a..9acf54763e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5728,6 +5728,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt13557.kt") + public void testKt13557() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt"); + doTest(fileName); + } + @TestMetadata("localVal.kt") public void testLocalVal() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");