From 1eb9a5a86d9838d08a48b9cf8a15285fcde2b058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Fri, 7 May 2021 14:16:13 +0200 Subject: [PATCH] JVM IR: Don't generate bridges for default argument stubs (KT-46389) --- .../FirBlackBoxCodegenTestGenerated.java | 12 ++++++++ .../backend/jvm/lower/BridgeLowering.kt | 12 ++++++-- .../testData/codegen/box/bridges/kt46389.kt | 23 ++++++++++++++ .../codegen/box/bridges/kt46389_jvmDefault.kt | 30 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++++++ .../LightAnalysisModeTestGenerated.java | 10 +++++++ .../IrJsCodegenBoxES6TestGenerated.java | 10 +++++++ .../IrJsCodegenBoxTestGenerated.java | 10 +++++++ .../semantics/JsCodegenBoxTestGenerated.java | 10 +++++++ .../IrCodegenBoxWasmTestGenerated.java | 10 +++++++ 11 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/bridges/kt46389.kt create mode 100644 compiler/testData/codegen/box/bridges/kt46389_jvmDefault.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 78113e45b72..2cc45c38aa5 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 @@ -2130,6 +2130,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @Test + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @Test + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @Test @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 73514ac78d3..3789703f7d2 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -200,8 +200,16 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass // Track final overrides and bridges to avoid clashes val blacklist = mutableSetOf() - // Add the current method to the blacklist if it is concrete or final. - val targetMethod = (irFunction.resolveFakeOverride() ?: irFunction).jvmMethod + // Don't generate bridges for default argument stubs. This is a workaround for a + // frontend bug (KT-36188). Ideally, the frontend should not allow inheriting from + // multiple different default argument stubs, but for now we need this special case + // to avoid a ClassCastException in the inliner (KT-46389). + val targetFunction = irFunction.resolveFakeOverride() ?: irFunction + if (targetFunction.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) { + return + } + // Add the current method to the blacklist if it is concrete or final + val targetMethod = targetFunction.jvmMethod if (!irFunction.isFakeOverride || irFunction.modality == Modality.FINAL) blacklist += targetMethod diff --git a/compiler/testData/codegen/box/bridges/kt46389.kt b/compiler/testData/codegen/box/bridges/kt46389.kt new file mode 100644 index 00000000000..b4ff7e03334 --- /dev/null +++ b/compiler/testData/codegen/box/bridges/kt46389.kt @@ -0,0 +1,23 @@ +// IGNORE_BACKEND: JS, JS_IR + +// The code in this test should be prohibited in the frontend, see KT-36188. + +// This test fails with an IllegalStateException on the JS(-IR) backend, +// but the behavior would probably not match the JVM backend even if +// the test passed. Compare with kt46389_jvmDefault. + +interface I { + fun h(x: String = "O"): Any +} + +interface I2 : I + +open class A { + inline fun h(x: String = "K") = x +} + +class B : A(), I2 + +fun box(): String { + return "${(B() as I).h()}${B().h()}" +} diff --git a/compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt b/compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt new file mode 100644 index 00000000000..80d37e2b92c --- /dev/null +++ b/compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt @@ -0,0 +1,30 @@ +// IGNORE_BACKEND: JS, JS_IR +// !JVM_DEFAULT_MODE: all +// JVM_TARGET: 1.8 + +// The code in this test should be prohibited in the frontend, see KT-36188. + +// Before the fix to kt46389, the IR backend would have added a bridge +// for `h$default` in `B`, which would have lead both calls to use "K" +// as the default value. This would arguably be less surprising, but is +// impossible to match without jvm-default on the JVM(-IR)backend. +// +// Meanwhile, the two calls using "K" as the default value is the current +// behavior on the JS backend, which is why the test is muted for the JS +// backend. + +interface I { + fun h(x: String = "O"): Any +} + +interface I2 : I + +open class A { + fun h(x: String = "K") = x +} + +class B : A(), I2 + +fun box(): String { + return "${(B() as I).h()}${B().h()}" +} 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 cd5b331c9d2..77038cd1fda 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 @@ -2058,6 +2058,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @Test + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @Test + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @Test @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() 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 6769943a4ee..34af738b427 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 @@ -2130,6 +2130,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @Test + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @Test + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @Test @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() 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 54be4ca765b..82397730a69 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -1808,6 +1808,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { runTest("compiler/testData/codegen/box/bridges/longChainOneBridge.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index e55808958ed..4b444347893 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -1273,6 +1273,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { runTest("compiler/testData/codegen/box/bridges/longChainOneBridge.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index f62983ee5c7..26ba167451a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -1273,6 +1273,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { runTest("compiler/testData/codegen/box/bridges/longChainOneBridge.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 61ebd71d6d0..aba3a292742 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -1253,6 +1253,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { runTest("compiler/testData/codegen/box/bridges/longChainOneBridge.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index d903482665d..3fd66b741ec 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -1138,6 +1138,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/bridges/kt42137.kt"); } + @TestMetadata("kt46389.kt") + public void testKt46389() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389.kt"); + } + + @TestMetadata("kt46389_jvmDefault.kt") + public void testKt46389_jvmDefault() throws Exception { + runTest("compiler/testData/codegen/box/bridges/kt46389_jvmDefault.kt"); + } + @TestMetadata("longChainOneBridge.kt") public void testLongChainOneBridge() throws Exception { runTest("compiler/testData/codegen/box/bridges/longChainOneBridge.kt");