From 64b911ea5e7289ee622c1ce2a28d2d907d0d1ff9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 9 Sep 2021 00:07:59 +0200 Subject: [PATCH] JVM IR: do not optimize casts for primitives in TypeOperatorLowering #KT-48659 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++++ .../backend/jvm/lower/TypeOperatorLowering.kt | 3 ++- .../kt48659_identityEqualsWithCastToAny.kt | 26 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.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 8bc82e60997..bb8c7ab5505 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 @@ -28824,6 +28824,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_long.kt"); } + @Test + @TestMetadata("kt48659_identityEqualsWithCastToAny.kt") + public void testKt48659_identityEqualsWithCastToAny() throws Exception { + runTest("compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt"); + } + @Test @TestMetadata("kt518.kt") public void testKt518() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt index 4e9434a1b38..c6705811373 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt @@ -100,7 +100,8 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil ) } } - argument.type.isSubtypeOfClass(type.erasedUpperBound.symbol) -> + // Do not optimize casts for values of primitive types because it can affect their identity and thus change behavior. + !argument.type.isPrimitiveType() && argument.type.isSubtypeOfClass(type.erasedUpperBound.symbol) -> argument else -> builder.irAs(argument, type) diff --git a/compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt b/compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt new file mode 100644 index 00000000000..75b0f69ff83 --- /dev/null +++ b/compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM + +fun int(a: Int, b: Int): Boolean = (a as Any) === (b as Any) +fun short(a: Short, b: Short): Boolean = (a as Any) === (b as Any) +fun char(a: Char, b: Char): Boolean = (a as Any) === (b as Any) +fun long(a: Long, b: Long): Boolean = (a as Any) === (b as Any) +fun float(a: Float, b: Float): Boolean = (a as Any) === (b as Any) +fun double(a: Double, b: Double): Boolean = (a as Any) === (b as Any) + +fun byte(a: Byte, b: Byte): Boolean = (a as Any) === (b as Any) +fun boolean(a: Boolean, b: Boolean): Boolean = (a as Any) === (b as Any) + +fun box(): String { + if (int(2021, 2021)) return "Fail int" + if (short(32042, 32042)) return "Fail short" + if (char(4242.toChar(), 4242.toChar())) return "Fail char" + if (long(4242424242L, 4242424242L)) return "Fail long" + if (float(3.14f, 3.14f)) return "Fail float" + if (double(2.72, 2.72)) return "Fail double" + + // All byte and boolean values are cached in java.lang.Byte/Boolean.valueOf + if (!byte(127, 127)) return "Fail byte" + if (!boolean(true, true)) return "Fail boolean" + + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 513fb08c448..835b8823e97 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -28692,6 +28692,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_long.kt"); } + @Test + @TestMetadata("kt48659_identityEqualsWithCastToAny.kt") + public void testKt48659_identityEqualsWithCastToAny() throws Exception { + runTest("compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt"); + } + @Test @TestMetadata("kt518.kt") public void testKt518() throws Exception { 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 1143cb40e22..2fdf6554b45 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 @@ -28824,6 +28824,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_long.kt"); } + @Test + @TestMetadata("kt48659_identityEqualsWithCastToAny.kt") + public void testKt48659_identityEqualsWithCastToAny() throws Exception { + runTest("compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt"); + } + @Test @TestMetadata("kt518.kt") public void testKt518() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 2611be90927..ae177d4ca4f 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -24375,6 +24375,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_long.kt"); } + @TestMetadata("kt48659_identityEqualsWithCastToAny.kt") + public void testKt48659_identityEqualsWithCastToAny() throws Exception { + runTest("compiler/testData/codegen/box/primitiveTypes/kt48659_identityEqualsWithCastToAny.kt"); + } + @TestMetadata("kt518.kt") public void testKt518() throws Exception { runTest("compiler/testData/codegen/box/primitiveTypes/kt518.kt");