JVM_IR: Add null-checks in SAM wrapper constructors (KT-50108)
This commit is contained in:
committed by
Alexander Udalov
parent
7f531d8426
commit
0da23198e6
+12
@@ -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 {
|
||||
|
||||
+1
-3
@@ -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
@@ -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"
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user