From 0af33462ef185921ad8ab9b4aab9bc06597105de Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 10 Aug 2018 14:22:41 +0300 Subject: [PATCH] Fix code generation for Array element access where C is inline class --- .../kotlin/codegen/ExpressionCodegen.java | 17 +++++------ .../accessArrayOfInlineClass.kt | 14 ++++++++++ .../accessArrayOfUnsigned.kt | 12 ++++++++ .../arrayOfInlineClassOfArrayOfInlineClass.kt | 23 +++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 28 +++++++++++++++++++ .../LightAnalysisModeTestGenerated.java | 28 +++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 28 +++++++++++++++++++ .../IrJsCodegenBoxTestGenerated.java | 28 +++++++++++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 28 +++++++++++++++++++ ...LegacyPrimitiveArraysBoxTestGenerated.java | 28 +++++++++++++++++++ 10 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt create mode 100644 compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt create mode 100644 compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 84b8133b263..f20b89b427a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -4256,21 +4256,22 @@ public class ExpressionCodegen extends KtVisitor impleme @Override public StackValue visitArrayAccessExpression(@NotNull KtArrayAccessExpression expression, StackValue receiver) { KtExpression array = expression.getArrayExpression(); - KotlinType type = array != null ? bindingContext.getType(array) : null; + KotlinType arrayKotlinType = array != null ? bindingContext.getType(array) : null; Type arrayType = expressionType(array); List indices = expression.getIndexExpressions(); FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(REFERENCE_TARGET, expression); assert operationDescriptor != null; - boolean isInlineClassType = type != null && InlineClassesUtilsKt.isInlineClassType(type); + boolean isInlineClassType = arrayKotlinType != null && InlineClassesUtilsKt.isInlineClassType(arrayKotlinType); if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && isInt(operationDescriptor.getValueParameters().get(0).getType()) && - !isInlineClassType) { - assert type != null; + !isInlineClassType + ) { + assert arrayKotlinType != null; + KotlinType elementKotlinType = state.getModule().getBuiltIns().getArrayElementType(arrayKotlinType); Type elementType; - if (KotlinBuiltIns.isArray(type)) { - KotlinType jetElementType = type.getArguments().get(0).getType(); - elementType = boxType(asmType(jetElementType)); + if (KotlinBuiltIns.isArray(arrayKotlinType)) { + elementType = boxType(asmType(elementKotlinType), elementKotlinType, state); } else { elementType = correctElementType(arrayType); @@ -4278,7 +4279,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, null, arrayValue, index); + return StackValue.arrayElement(elementType, elementKotlinType, arrayValue, index); } else { ResolvedCall resolvedSetCall = bindingContext.get(INDEXED_LVALUE_SET, expression); diff --git a/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt new file mode 100644 index 00000000000..accbe5cdeea --- /dev/null +++ b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR, JS_IR + +inline class Z(val data: Int) + +val xs = Array(2) { Z(42) } + +fun box(): String { + xs[0] = Z(12) + val t = xs[0] + if (t.data != 12) throw AssertionError("$t") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt new file mode 100644 index 00000000000..62c26cebe79 --- /dev/null +++ b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt @@ -0,0 +1,12 @@ +// WITH_UNSIGNED +// IGNORE_BACKEND: JVM_IR, JS_IR, JS + +val xs = Array(2) { 42u } + +fun box(): String { + xs[0] = 12u + val t = xs[0] + if (t != 12u) throw AssertionError("$t") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt new file mode 100644 index 00000000000..45b443f01ab --- /dev/null +++ b/compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt @@ -0,0 +1,23 @@ +// !LANGUAGE: +InlineClasses +// WITH_UNSIGNED +// IGNORE_BACKEND: JVM_IR, JS_IR, JS + +inline class Data(val data: Array) + +val D = + Array(4) { i -> + Data(Array(4) { j -> + (i + j).toUInt() + }) + } + +fun box(): String { + for (i in D.indices) { + for (j in D[i].data.indices) { + val x = D[i].data[j].toInt() + if (x != i + j) throw AssertionError() + } + } + + return "OK" +} \ 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 e62c478957a..ff53bbd7ed5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -590,6 +590,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/arrays/varargsWithJava.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1e62f715bd4..504847aa476 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -590,6 +590,34 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/arrays/varargsWithJava.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 36e6c8ef3a9..7ee7005e0a2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -590,6 +590,34 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/arrays/varargsWithJava.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index 44d9075e9fd..923d9b25c57 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -580,6 +580,34 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/arrays/stdlib.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) 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 37271ed0eb8..35df04d9c6c 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 @@ -580,6 +580,34 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/arrays/stdlib.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsLegacyPrimitiveArraysBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsLegacyPrimitiveArraysBoxTestGenerated.java index 7559009e286..4857ce80ff3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsLegacyPrimitiveArraysBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsLegacyPrimitiveArraysBoxTestGenerated.java @@ -329,6 +329,34 @@ public class JsLegacyPrimitiveArraysBoxTestGenerated extends AbstractJsLegacyPri runTest("compiler/testData/codegen/box/arrays/stdlib.kt"); } + @TestMetadata("compiler/testData/codegen/box/arrays/arraysOfInlineClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ArraysOfInlineClass extends AbstractJsLegacyPrimitiveArraysBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + @TestMetadata("accessArrayOfInlineClass.kt") + public void testAccessArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfInlineClass.kt"); + } + + @TestMetadata("accessArrayOfUnsigned.kt") + public void testAccessArrayOfUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/accessArrayOfUnsigned.kt"); + } + + public void testAllFilesPresentInArraysOfInlineClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/arraysOfInlineClass"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("arrayOfInlineClassOfArrayOfInlineClass.kt") + public void testArrayOfInlineClassOfArrayOfInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/arrays/arraysOfInlineClass/arrayOfInlineClassOfArrayOfInlineClass.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/arrays/multiDecl") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)