JVM_IR: Add null-checks in SAM wrapper constructors (KT-50108)

This commit is contained in:
Steven Schäfer
2021-12-08 11:17:58 +01:00
committed by Alexander Udalov
parent 7f531d8426
commit 0da23198e6
7 changed files with 102 additions and 3 deletions
@@ -44609,6 +44609,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/sam/kt49226.kt");
}
@Test
@TestMetadata("kt50108.kt")
public void testKt50108() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108.kt");
}
@Test
@TestMetadata("kt50108_java.kt")
public void testKt50108_java() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108_java.kt");
}
@Test
@TestMetadata("kt50171.kt")
public void testKt50171() throws Exception {
@@ -291,9 +291,7 @@ class ExpressionCodegen(
irFunction.origin.isSynthetic ||
// TODO: refine this condition to not generate nullability assertions on parameters
// corresponding to captured variables and anonymous object super constructor arguments
(irFunction is IrConstructor &&
(irFunction.parentAsClass.isAnonymousObject ||
irFunction.parentAsClass.origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION)) ||
(irFunction is IrConstructor && irFunction.parentAsClass.isAnonymousObject) ||
// TODO: Implement this as a lowering, so that we can more easily exclude generated methods.
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
// Although these are accessible from Java, the functions they bridge to already have the assertions.
+32
View File
@@ -0,0 +1,32 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
fun interface IFoo {
fun foo(): String
}
abstract class Base {
abstract val fn: () -> String
init {
// This should throw a NPE, since the constructor of the IFoo
// SAM wrapper expects a non-nullable function type.
//
// In the JVM backend this expression evaluates to `null` instead,
// which isn't a valid result according to the type system.
IFoo(fn)
}
}
class Derived : Base() {
override val fn: () -> String = { "OK" }
}
fun box(): String {
try {
Derived()
} catch (e: java.lang.NullPointerException) {
return "OK"
}
return "Fail"
}
+23
View File
@@ -0,0 +1,23 @@
// TARGET_BACKEND: JVM
// FILE: test.kt
fun interface IFoo {
fun foo(s: String)
}
val foo = IFoo {}
fun box(): String {
try {
J.callWithNull(foo)
return "J.callWithNull(foo) should throw NPE"
} catch (e: NullPointerException) {
return "OK"
}
}
// FILE: J.java
public class J {
public static void callWithNull(IFoo iFoo) {
iFoo.foo(null);
}
}
@@ -44063,6 +44063,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/sam/kt49226.kt");
}
@Test
@TestMetadata("kt50108.kt")
public void testKt50108() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108.kt");
}
@Test
@TestMetadata("kt50108_java.kt")
public void testKt50108_java() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108_java.kt");
}
@Test
@TestMetadata("kt50171.kt")
public void testKt50171() throws Exception {
@@ -44609,6 +44609,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/sam/kt49226.kt");
}
@Test
@TestMetadata("kt50108.kt")
public void testKt50108() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108.kt");
}
@Test
@TestMetadata("kt50108_java.kt")
public void testKt50108_java() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108_java.kt");
}
@Test
@TestMetadata("kt50171.kt")
public void testKt50171() throws Exception {
@@ -35460,6 +35460,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Sam extends AbstractLightAnalysisModeTest {
@TestMetadata("kt50108.kt")
public void ignoreKt50108() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@@ -35593,6 +35598,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/sam/kt49226.kt");
}
@TestMetadata("kt50108_java.kt")
public void testKt50108_java() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50108_java.kt");
}
@TestMetadata("kt50171.kt")
public void testKt50171() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50171.kt");