JVM IR: Don't generate null checks on value parameters of private operator functions

The null check on the extension receiver of private operator functions
is a special case and doesn't extend to value parameters.
This commit is contained in:
Steven Schäfer
2020-11-03 15:13:22 +01:00
committed by Alexander Udalov
parent d4cb521433
commit bd4e2a283c
6 changed files with 88 additions and 1 deletions
@@ -16119,6 +16119,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/paramAssertionMessage.kt");
}
@TestMetadata("privateOperatorParameterAssertions.kt")
public void testPrivateOperatorParameterAssertions() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/privateOperatorParameterAssertions.kt");
}
@TestMetadata("staticCallErrorMessage.kt")
public void testStaticCallErrorMessage() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
@@ -305,7 +305,12 @@ class ExpressionCodegen(
return
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) }
irFunction.valueParameters.forEach(::generateNonNullAssertion)
// Private operator functions don't have null checks on value parameters,
// see `DescriptorAsmUtil.genNotNullAssertionsForParameters`.
if (!DescriptorVisibilities.isPrivate(irFunction.visibility) || irFunction !is IrSimpleFunction || !irFunction.isOperator) {
irFunction.valueParameters.forEach(::generateNonNullAssertion)
}
}
private fun generateNonNullAssertion(param: IrValueParameter) {
@@ -0,0 +1,62 @@
// TARGET_BACKEND: JVM
// WITH_REFLECT
var result: String? = "fail"
class X
class A {
// There should be a null check on the extension receiver of private
// operator functions, but no null checks on all other arguments.
private operator fun X.get(name: String) = "$name$result"
private operator fun X.set(name: String, v: String) {
result = v
}
private fun getMethod(name: String) =
A::class.java.getDeclaredMethods().first { it.name == name }
fun test(): String {
val setter = getMethod("set")
try {
setter.invoke(this, X(), null, null)
} catch (e: Throwable) {
return "Fail 1"
}
try {
setter.invoke(this, null, null, null)
return "Fail 2"
} catch (e: Throwable) {
// expected
if (e.cause !is NullPointerException) {
return "Fail 3"
}
}
val getter = getMethod("get")
val s = try {
getter.invoke(this, X(), null) as String
} catch (e: Throwable) {
return "Fail 4"
}
try {
getter.invoke(this, null, null)
return "Fail 5"
} catch (e: Throwable) {
// expected
if (e.cause !is NullPointerException) {
return "Fail 6"
}
}
return if (s == "nullnull") "OK" else "Fail 7"
}
}
fun box(): String {
return A().test()
}
@@ -17519,6 +17519,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/paramAssertionMessage.kt");
}
@TestMetadata("privateOperatorParameterAssertions.kt")
public void testPrivateOperatorParameterAssertions() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/privateOperatorParameterAssertions.kt");
}
@TestMetadata("staticCallErrorMessage.kt")
public void testStaticCallErrorMessage() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
@@ -17519,6 +17519,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/paramAssertionMessage.kt");
}
@TestMetadata("privateOperatorParameterAssertions.kt")
public void testPrivateOperatorParameterAssertions() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/privateOperatorParameterAssertions.kt");
}
@TestMetadata("staticCallErrorMessage.kt")
public void testStaticCallErrorMessage() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
@@ -16119,6 +16119,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/paramAssertionMessage.kt");
}
@TestMetadata("privateOperatorParameterAssertions.kt")
public void testPrivateOperatorParameterAssertions() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/privateOperatorParameterAssertions.kt");
}
@TestMetadata("staticCallErrorMessage.kt")
public void testStaticCallErrorMessage() throws Exception {
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");