diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 2c38dc02f6c..5f4983cd45c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3557,7 +3557,7 @@ public class ExpressionCodegen extends KtVisitor impleme StackValue base = genQualified(receiver, expression.getBaseExpression()); if (isPrimitive(base.type)) return base; - return StackValue.operation(base.type, v -> { + return StackValue.operation(base.type, base.kotlinType, v -> { base.put(base.type, base.kotlinType, v); v.dup(); Label ok = new Label(); diff --git a/compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt b/compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt new file mode 100644 index 00000000000..a0dd4e81efc --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt @@ -0,0 +1,47 @@ +// !LANGUAGE: +InlineClasses + +inline class WithPrimitive(val a: Int) +fun takeWithPrimitive(a: WithPrimitive) {} + +inline class WithReference(val a: Any) +fun takeWithReference(a: WithReference) {} + +inline class WithNullableReference(val a: Any?) +fun takeWithNullableReference(a: WithNullableReference) {} + +fun foo(a: WithPrimitive?, b: WithPrimitive) { + takeWithPrimitive(a!!) // unbox + takeWithPrimitive(a) // unbox + takeWithPrimitive(b!!) +} + +fun bar(a: WithReference?, b: WithReference) { + takeWithReference(a!!) + takeWithReference(a) + takeWithReference(b!!) +} + +fun baz(a: WithNullableReference?, b: WithNullableReference) { + takeWithNullableReference(a!!) // unbox + takeWithNullableReference(a) // unbox + takeWithNullableReference(a!!) // unbox + takeWithNullableReference(b!!) +} + +fun box(): String { + val a1 = WithPrimitive(1) + val b1 = WithPrimitive(2) + + foo(a1, b1) + + val a2 = WithReference("") + + bar(a2, a2) + + val a3 = WithNullableReference("test") + val a4 = WithNullableReference(123) + + baz(a3, a4) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassesUnboxingAfterAssertionOperator.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassesUnboxingAfterAssertionOperator.kt new file mode 100644 index 00000000000..d73dafcb88e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassesUnboxingAfterAssertionOperator.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +InlineClasses + +inline class WithPrimitive(val a: Int) +fun takeWithPrimitive(a: WithPrimitive) {} + +inline class WithReference(val a: Any) +fun takeWithReference(a: WithReference) {} + +inline class WithNullableReference(val a: Any?) +fun takeWithNullableReference(a: WithNullableReference) {} + +fun foo(a: WithPrimitive?, b: WithPrimitive) { + takeWithPrimitive(a!!) // unbox + takeWithPrimitive(a) // unbox + takeWithPrimitive(b!!) +} + +fun bar(a: WithReference?, b: WithReference) { + takeWithReference(a!!) + takeWithReference(a) + takeWithReference(b!!) +} + +fun baz(a: WithNullableReference?, b: WithNullableReference) { + takeWithNullableReference(a!!) // unbox + takeWithNullableReference(a) // unbox + takeWithNullableReference(a!!) // unbox + takeWithNullableReference(b!!) +} + +// 2 INVOKEVIRTUAL WithPrimitive\.unbox +// 0 INVOKEVIRTUAL WithReference\.unbox +// 3 INVOKEVIRTUAL WithNullableReference\.unbox + +// 0 intValue +// 0 valueOf \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index e7b4019a26b..02c5d1780f3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1950,6 +1950,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("inlineClassesUnboxingAfterAssertionOperator.kt") + public void testInlineClassesUnboxingAfterAssertionOperator() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassesUnboxingAfterAssertionOperator.kt"); + doTest(fileName); + } + @TestMetadata("unboxInlineClassAfterSafeCall.kt") public void testUnboxInlineClassAfterSafeCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterSafeCall.kt");