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 f8ae7fa6650..ca07a2ff6b5 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 @@ -19939,6 +19939,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt"); } + @Test + @TestMetadata("nullabilityAssertions.kt") + public void testNullabilityAssertions() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt"); + } + @Test @TestMetadata("possibleOverrideClash.kt") public void testPossibleOverrideClash() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 8137dd38511..55a879d4acd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -275,7 +275,7 @@ class ExpressionCodegen( return if (inlinedInto != null || - (DescriptorVisibilities.isPrivate(irFunction.visibility) && !(irFunction is IrSimpleFunction && irFunction.isOperator)) || + (DescriptorVisibilities.isPrivate(irFunction.visibility) && !shouldGenerateNonNullAssertionsForPrivateFun(irFunction)) || irFunction.origin.isSynthetic || // TODO: refine this condition to not generate nullability assertions on parameters // corresponding to captured variables and anonymous object super constructor arguments @@ -310,6 +310,13 @@ class ExpressionCodegen( } } + // * Operator functions require non-null assertions on parameters even if they are private. + // * Local function for lambda survives at this stage if it was used in 'invokedynamic'-based code. + // Such functions require non-null assertions on parameters. + private fun shouldGenerateNonNullAssertionsForPrivateFun(irFunction: IrFunction) = + irFunction is IrSimpleFunction && irFunction.isOperator || + irFunction.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA + private fun generateNonNullAssertion(param: IrValueParameter) { val asmType = param.type.asmType if (!param.type.unboxInlineClass().isNullable() && !isPrimitive(asmType)) { diff --git a/compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt b/compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt new file mode 100644 index 00000000000..b2f0ad4784f --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// SAM_CONVERSIONS: INDY +// FILE: nullabilityAssertions.kt +fun box(): String { + fun justSomeLocalFun() {} + + try { + A.bar {} + } catch (e: NullPointerException) { + return "OK" + } + + return "Should throw NullPointerException" +} + +// FILE: A.java +import org.jetbrains.annotations.NotNull; + +public interface A { + void foo(@NotNull String s); + + static void bar(A a) { + a.foo(null); + } +} 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 87ab19a4bd0..34067e8e477 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 @@ -19939,6 +19939,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt"); } + @Test + @TestMetadata("nullabilityAssertions.kt") + public void testNullabilityAssertions() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt"); + } + @Test @TestMetadata("possibleOverrideClash.kt") public void testPossibleOverrideClash() 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 621b350cdf9..05ecd8000c8 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 @@ -19939,6 +19939,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt"); } + @Test + @TestMetadata("nullabilityAssertions.kt") + public void testNullabilityAssertions() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt"); + } + @Test @TestMetadata("possibleOverrideClash.kt") public void testPossibleOverrideClash() 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 4e50a92496b..e5101b1bdb2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16718,6 +16718,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt"); } + @TestMetadata("nullabilityAssertions.kt") + public void testNullabilityAssertions() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/nullabilityAssertions.kt"); + } + @TestMetadata("possibleOverrideClash.kt") public void testPossibleOverrideClash() throws Exception { runTest("compiler/testData/codegen/box/invokedynamic/sam/possibleOverrideClash.kt");