From 7c015564ce8ecc28ae27298e0840be9299c2db9d Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 20 Nov 2019 12:06:17 +0100 Subject: [PATCH] JVM_IR: do not set ACC_VARARGS if vararg is not the last parameter Fun fact: this is not actually validated when loading the class; and even when compiling a java file against a class file that does this, only javac 9 has a check (1.8 and before simply crashes with NullPointerException somewhere deep inside the compiler). --- .../kotlin/backend/jvm/codegen/FunctionCodegen.kt | 2 +- .../codegen/box/vararg/notInLastPosition.kt | 15 +++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../codegen/LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ 6 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/vararg/notInLastPosition.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 4b56a822a71..0fd29c08794 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -108,7 +108,7 @@ open class FunctionCodegen( val visibility = irFunction.getVisibilityAccessFlag() val staticFlag = if (isStatic) Opcodes.ACC_STATIC else 0 - val varargFlag = if (irFunction.valueParameters.any { it.varargElementType != null }) Opcodes.ACC_VARARGS else 0 + val varargFlag = if (irFunction.valueParameters.lastOrNull()?.varargElementType != null) Opcodes.ACC_VARARGS else 0 val deprecation = irFunction.deprecationFlags val bridgeFlag = if ( irFunction.origin == IrDeclarationOrigin.BRIDGE || diff --git a/compiler/testData/codegen/box/vararg/notInLastPosition.kt b/compiler/testData/codegen/box/vararg/notInLastPosition.kt new file mode 100644 index 00000000000..81df652f6fa --- /dev/null +++ b/compiler/testData/codegen/box/vararg/notInLastPosition.kt @@ -0,0 +1,15 @@ +// TARGET_BACKEND: JVM +// FILE: A.kt +class A { + fun f(vararg xs: String, y: String) = xs[0] + y +} + +// FILE: B.java +public class B { + public static String f() { + return new A().f(new String[]{"O"}, "K"); + } +} + +// FILE: C.kt +fun box() = B.f() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 9af860a2c72..4e302ba7a26 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -27773,6 +27773,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/vararg/kt796_797.kt"); } + @TestMetadata("notInLastPosition.kt") + public void testNotInLastPosition() throws Exception { + runTest("compiler/testData/codegen/box/vararg/notInLastPosition.kt"); + } + @TestMetadata("singleAssignmentToVarargsInFunction.kt") public void testSingleAssignmentToVarargsInFunction() throws Exception { runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 653042a30b3..9e56e52ca59 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -26590,6 +26590,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/vararg/kt796_797.kt"); } + @TestMetadata("notInLastPosition.kt") + public void testNotInLastPosition() throws Exception { + runTest("compiler/testData/codegen/box/vararg/notInLastPosition.kt"); + } + @TestMetadata("singleAssignmentToVarargsInFunction.kt") public void testSingleAssignmentToVarargsInFunction() throws Exception { runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index dc48af0497e..c6deaf255a0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -26323,6 +26323,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/vararg/kt796_797.kt"); } + @TestMetadata("notInLastPosition.kt") + public void testNotInLastPosition() throws Exception { + runTest("compiler/testData/codegen/box/vararg/notInLastPosition.kt"); + } + @TestMetadata("singleAssignmentToVarargsInFunction.kt") public void testSingleAssignmentToVarargsInFunction() throws Exception { runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cf725fe7c47..8fb1a5f2222 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -26323,6 +26323,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/vararg/kt796_797.kt"); } + @TestMetadata("notInLastPosition.kt") + public void testNotInLastPosition() throws Exception { + runTest("compiler/testData/codegen/box/vararg/notInLastPosition.kt"); + } + @TestMetadata("singleAssignmentToVarargsInFunction.kt") public void testSingleAssignmentToVarargsInFunction() throws Exception { runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt");