diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 65b5353f9be..c8bdac33ea1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2832,13 +2832,16 @@ public class ExpressionCodegen extends KtVisitor impleme } } else { - return StackValue.operation(type, adapter -> { + return StackValue.operation(type, outType, adapter -> { v.iconst(arguments.size()); newArrayInstruction(outType); + KotlinType elementKotlinType = outType.getConstructor().getBuiltIns().getArrayElementType(outType); for (int i = 0; i != size; ++i) { v.dup(); StackValue rightSide = gen(arguments.get(i).getArgumentExpression()); - StackValue.arrayElement(elementType, StackValue.onStack(type), StackValue.constant(i, Type.INT_TYPE)).store(rightSide, v); + StackValue + .arrayElement(elementType, elementKotlinType, StackValue.onStack(type, outType), StackValue.constant(i, Type.INT_TYPE)) + .store(rightSide, v); } return Unit.INSTANCE; }); @@ -4056,7 +4059,7 @@ public class ExpressionCodegen extends KtVisitor impleme elementJetType, ReifiedTypeInliner.OperationKind.NEW_ARRAY ); - v.newarray(boxType(asmType(elementJetType))); + v.newarray(boxType(typeMapper.mapTypeAsDeclaration(elementJetType))); } else { Type type = typeMapper.mapType(arrayType); @@ -4089,7 +4092,7 @@ public class ExpressionCodegen extends KtVisitor impleme StackValue arrayValue = genLazy(array, arrayType); StackValue index = genLazy(indices.get(0), Type.INT_TYPE); - return StackValue.arrayElement(elementType, arrayValue, index); + return StackValue.arrayElement(elementType, null, arrayValue, index); } else { ResolvedCall resolvedSetCall = bindingContext.get(INDEXED_LVALUE_SET, expression); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 7dbd101467b..ce967d7c8e5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -584,7 +584,7 @@ public class PropertyCodegen { StackValue.Field array = StackValue.field( Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none() ); - return StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE)); + return StackValue.arrayElement(K_PROPERTY_TYPE, null, array, StackValue.constant(index, Type.INT_TYPE)); } private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index f944dd4988e..1e161db953d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -279,8 +279,8 @@ public abstract class StackValue { } @NotNull - public static StackValue arrayElement(@NotNull Type type, StackValue array, StackValue index) { - return new ArrayElement(type, array, index); + public static StackValue arrayElement(@NotNull Type type, @Nullable KotlinType kotlinType, StackValue array, StackValue index) { + return new ArrayElement(type, kotlinType, array, index); } @NotNull @@ -1004,8 +1004,8 @@ public abstract class StackValue { private static class ArrayElement extends StackValueWithSimpleReceiver { private final Type type; - public ArrayElement(Type type, StackValue array, StackValue index) { - super(type, null, false, false, new Receiver(Type.LONG_TYPE, array, index), true); + public ArrayElement(Type type, KotlinType kotlinType, StackValue array, StackValue index) { + super(type, kotlinType, false, false, new Receiver(Type.LONG_TYPE, array, index), true); this.type = type; } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 600273d8449..8c6a258a7eb 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -472,11 +472,14 @@ class ExpressionCodegen( else { mv.iconst(size) newArrayInstruction(expression.type) + val elementKotlinType = outType.constructor.builtIns.getArrayElementType(outType) for ((i, element) in expression.elements.withIndex()) { mv.dup() StackValue.constant(i, Type.INT_TYPE).put(Type.INT_TYPE, mv) val rightSide = gen(element, elementType, data) - StackValue.arrayElement(elementType, StackValue.onStack(elementType), StackValue.onStack(Type.INT_TYPE)).store(rightSide, mv) + StackValue + .arrayElement(elementType, elementKotlinType, StackValue.onStack(elementType, outType), StackValue.onStack(Type.INT_TYPE)) + .store(rightSide, mv) } } return expression.onStack diff --git a/compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt b/compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt new file mode 100644 index 00000000000..6b6520f44ea --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt @@ -0,0 +1,24 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val value: Int) + +fun takeVarargs(vararg e: T): T { + return e[e.size - 1] +} + +fun test(u1: UInt, u2: UInt, u3: UInt?): Int { + val a = takeVarargs(u1, u2) + val b = takeVarargs(u3) ?: UInt(-1) + val c = takeVarargs(u1, u3) ?: UInt(-1) + + return a.value + b.value + c.value +} + +fun box(): String { + val u1 = UInt(0) + val u2 = UInt(1) + val u3 = UInt(2) + if (test(u1, u2, u3) != 1 + 2 + 2) return "fail" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt new file mode 100644 index 00000000000..dc1c07d587b --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val u: Int) + +fun takeVarargs(vararg e: T) {} + +fun test(u1: UInt, u2: UInt, u3: UInt?) { + takeVarargs(u1, u2) // 2 box + takeVarargs(u3) + takeVarargs(u1, u3) // box +} + +// 3 INVOKESTATIC UInt\$Erased.box +// 0 INVOKEVIRTUAL UInt.unbox + +// 0 valueOf +// 0 intValue \ No newline at end of file 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 298fcb20a2b..953e20f9fe9 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 @@ -10491,6 +10491,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("passInlineClassAsVararg.kt") + public void testPassInlineClassAsVararg() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt"); + doTest(fileName); + } + @TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt") public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index cec51997212..a7a1f1e3ebf 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10491,6 +10491,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("passInlineClassAsVararg.kt") + public void testPassInlineClassAsVararg() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt"); + doTest(fileName); + } + @TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt") public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index eb4e3cd06c0..cdef08e562c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1920,6 +1920,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("boxInlineClassesOnPassingToVarargs.kt") + public void testBoxInlineClassesOnPassingToVarargs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt"); + doTest(fileName); + } + @TestMetadata("boxResultAfterConstructorCall.kt") public void testBoxResultAfterConstructorCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultAfterConstructorCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 200042498dc..386c2797896 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10491,6 +10491,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("passInlineClassAsVararg.kt") + public void testPassInlineClassAsVararg() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt"); + doTest(fileName); + } + @TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt") public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b214990d491..26a721f739b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11475,6 +11475,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("passInlineClassAsVararg.kt") + public void testPassInlineClassAsVararg() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt"); + doTest(fileName); + } + @TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt") public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt");