JVM IR: Don't generate bridges for default argument stubs (KT-46389)

This commit is contained in:
Steven Schäfer
2021-05-07 14:16:13 +02:00
committed by Alexander Udalov
parent 40b5a7d449
commit 1eb9a5a86d
11 changed files with 149 additions and 2 deletions
@@ -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 {
@@ -200,8 +200,16 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
// Track final overrides and bridges to avoid clashes
val blacklist = mutableSetOf<Method>()
// 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
+23
View File
@@ -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()}"
}
@@ -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()}"
}
@@ -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 {
@@ -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 {
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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");