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 a5d9c90b6f3..8f1f0145f70 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 @@ -27486,6 +27486,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @Test + @TestMetadata("kt49136.kt") + public void testKt49136() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt"); + } + + @Test + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @Test @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt index 8593f9b04ac..78cfc46a07e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt @@ -64,4 +64,7 @@ interface CommonBackendContext : BackendContext, LoggingContext { val optimizeLoopsOverUnsignedArrays: Boolean get() = false + + val optimizeNullChecksUsingKotlinNullability: Boolean + get() = true } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt index c0cea9a9d1e..a53d82cd185 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt @@ -146,9 +146,9 @@ class IfNullExpressionsFusionLowering(val context: CommonBackendContext) : FileL is IrGetClass -> false is IrCall -> - if (!type.isNullable()) false else null + if (context.optimizeNullChecksUsingKotlinNullability && !type.isNullable()) false else null is IrGetField -> - if (!type.isNullable()) false else null + if (context.optimizeNullChecksUsingKotlinNullability && !type.isNullable()) false else null is IrBlock -> { val singleExpr = statements.singleOrNull() if (singleExpr is IrExpression && singleExpr.type == type) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index a5b53930a3a..bcbdad0d563 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -221,6 +221,9 @@ class JvmBackendContext( override val doWhileCounterLoopOrigin: IrStatementOrigin get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP + override val optimizeNullChecksUsingKotlinNullability: Boolean + get() = false + inner class JvmIr( irModuleFragment: IrModuleFragment, symbolTable: SymbolTable diff --git a/compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt b/compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt new file mode 100644 index 00000000000..2d546a0417a --- /dev/null +++ b/compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt @@ -0,0 +1,20 @@ +// TARGET_BACKEND: JVM +// FULL_JDK +// WITH_REFLECT + +class A(val b: B) + +class B(val c: String) + +fun createByReflection(): A? = + A(B("aaa")).apply { + val field = javaClass.declaredFields.find { it.name == "b" }!! + field.isAccessible = true + field.set(this, null) + } + +fun box(): String { + val a = createByReflection() + println(a?.b?.c) + return "OK" +} diff --git a/compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt b/compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt new file mode 100644 index 00000000000..b34bb2fe1e2 --- /dev/null +++ b/compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt @@ -0,0 +1,22 @@ +abstract class Z { + init { + check(this) + } + + abstract val b: B +} + +class A(override val b: B) : Z() + +class B(val c: String) + +fun use(a: Any?) {} + +fun check(z: Z) { + use(z?.b?.c) +} + +fun box(): String { + A(B("")) + return "OK" +} 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 7a437fa85b6..80331de86fe 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 @@ -27348,6 +27348,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @Test + @TestMetadata("kt49136.kt") + public void testKt49136() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt"); + } + + @Test + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @Test @TestMetadata("kt7774.kt") public void testKt7774() 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 adb47408df1..e5fa8cddb4e 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 @@ -27486,6 +27486,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @Test + @TestMetadata("kt49136.kt") + public void testKt49136() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt"); + } + + @Test + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @Test @TestMetadata("kt7774.kt") public void testKt7774() 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 c48e76fc005..8711d4295ba 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -23199,6 +23199,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @TestMetadata("kt49136.kt") + public void testKt49136() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136.kt"); + } + + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index b14ef72b7e7..73e1808d810 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -18138,6 +18138,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 638af2fe335..9d3344b0fba 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -17544,6 +17544,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 7b10c05e75f..0aa57e0ee29 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -17574,6 +17574,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 6b38369bf6a..a23cf027bde 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -14323,6 +14323,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt"); } + @TestMetadata("kt49136a.kt") + public void testKt49136a() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/kt49136a.kt"); + } + @TestMetadata("kt7774.kt") public void testKt7774() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt");