From db133bedf9cbe36ce21a261e77295838ded02211 Mon Sep 17 00:00:00 2001 From: "vladislav.grechko" Date: Thu, 20 Oct 2022 16:49:16 +0200 Subject: [PATCH] Fix ClassCastException on equality comparison on inline class objects ^KT-54603: Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++ .../jvm/lower/JvmInlineClassLowering.kt | 5 +- .../codegen/box/inlineClasses/kt54603.kt | 68 +++++++++++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/kt54603.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 84acbf32568..c66dd900c86 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -22265,6 +22265,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/kt54455.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("kt54603.kt") + public void testKt54603() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt54603.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt index 5570a427b67..5db4f804020 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt @@ -497,9 +497,10 @@ private class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClass fun irBox(expr: IrExpression) = irCall(boxFunction).apply { putValueArgument(0, expr) } + val underlyingType = getInlineClassUnderlyingType(valueClass) irCall(untypedEquals).apply { - dispatchReceiver = irBox(irGet(left)) - putValueArgument(0, irBox(irGet(right))) + dispatchReceiver = irBox(coerceInlineClasses(irGet(left), left.type, underlyingType)) + putValueArgument(0, irBox(coerceInlineClasses(irGet(right), right.type, underlyingType))) } } else { irEquals(coerceInlineClasses(irGet(left), left.type, type), coerceInlineClasses(irGet(right), right.type, type)) diff --git a/compiler/testData/codegen/box/inlineClasses/kt54603.kt b/compiler/testData/codegen/box/inlineClasses/kt54603.kt new file mode 100644 index 00000000000..89c62cf11e4 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt54603.kt @@ -0,0 +1,68 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses, +CustomEqualsInInlineClasses +// TARGET_BACKEND: JVM_IR + +class A(x: Int) + +OPTIONAL_JVM_INLINE_ANNOTATION +value class B(val a: A) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class C(val t: T) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class D(val t: T) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class E(val d: Double) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class F(val e: E) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class G(val e: Int?) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class H(val e: Any?) { + override fun equals(other: Any?) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class I(val e: E?) { + override fun equals(other: Any?) = true +} + +fun box(): String { + if (B(A(0)) != B(A(5))) return "Fail 1" + if (C(0) != C("a")) return "Fail 2" + if (D(0) != D(2)) return "Fail 3" + if (E(0.0) != E(0.5)) return "Fail 4" + if (F(E(0.0)) != F(E(0.5))) return "Fail 5" + + if (G(0) != G(2)) return "Fail 6.1" + if (G(0) != G(null)) return "Fail 6.2" + if (G(null) != G(0)) return "Fail 6.3" + + if (H("aba") != H("caba")) return "Fail 7.1" + if (H("aba") != H(null)) return "Fail 7.2" + if (H(null) != H("caba")) return "Fail 7.3" + + if (I(E(0.0)) != I(E(0.5))) return "Fail 8.1" + if (I(E(0.0)) != I(null)) return "Fail 8.2" + if (I(null) != I(E(0.5))) return "Fail 8.3" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 0de92ffe8a6..bf6c01842b8 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -22265,6 +22265,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/kt54455.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("kt54603.kt") + public void testKt54603() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt54603.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception {