JVM: do not put public field access into a single expression block
It affects the `is IrGetField` check in TypeOperatorLowering.computeNotNullAssertionText, which leads to missing NPE messages when accessing backing fields of public properties. #KT-64615
This commit is contained in:
committed by
Space Team
parent
96b2f13397
commit
f01e633f8b
+6
@@ -31436,6 +31436,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31436,6 +31436,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31045,6 +31045,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31045,6 +31045,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31045,6 +31045,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+4
-1
@@ -136,9 +136,12 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
} else {
|
} else {
|
||||||
+irGetField(receiver.takeUnless { backingField.isStatic }, backingField)
|
+irGetField(receiver.takeUnless { backingField.isStatic }, backingField)
|
||||||
}
|
}
|
||||||
}
|
}.unwrapSingleExpressionBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrExpression.unwrapSingleExpressionBlock(): IrExpression =
|
||||||
|
(this as? IrBlock)?.statements?.singleOrNull() as? IrExpression ?: this
|
||||||
|
|
||||||
override fun visitWhen(expression: IrWhen, data: IrDeclaration?): IrExpression {
|
override fun visitWhen(expression: IrWhen, data: IrDeclaration?): IrExpression {
|
||||||
val isCompilerGenerated = expression.origin == null
|
val isCompilerGenerated = expression.origin == null
|
||||||
expression.transformChildren(this, data)
|
expression.transformChildren(this, data)
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// !LANGUAGE: +NoSourceCodeInNotNullAssertionExceptions
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
val publicProperty = J().s()
|
||||||
|
private val privateProperty = J().s()
|
||||||
|
|
||||||
|
fun f(x: String) = "Fail 1"
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
try {
|
||||||
|
f(publicProperty)
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
if (e.message != "publicProperty must not be null") return "Fail 2: ${e.message}"
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
f(privateProperty)
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
if (e.message != "privateProperty must not be null") return "Fail 3: ${e.message}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
public class J {
|
||||||
|
public final String s() { return null; }
|
||||||
|
}
|
||||||
+6
@@ -31045,6 +31045,12 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -29323,6 +29323,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31045,6 +31045,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+6
@@ -31045,6 +31045,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
|
|||||||
+5
@@ -26297,6 +26297,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("field_after.kt")
|
@TestMetadata("field_after.kt")
|
||||||
public void testField_after() throws Exception {
|
public void testField_after() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/field_after.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/expressionAssertionMessages/field_after.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user