diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt index fcb282ab2a3ed..d09d7ea2295b7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt @@ -161,7 +161,7 @@ private fun Type.isIntLike(): Boolean = when (sort) { } // Represents [ACONST_NULL, CHECKCAST Type] sequence result. -internal class TypedNullValue(type: Type) : BasicValue(type) +internal class TypedNullValue(type: Type) : StrictBasicValue(type) // Preserves nulls through CHECKCASTS. private class NullCheckcastAwareOptimizationBasicInterpreter : OptimizationBasicInterpreter() { @@ -171,4 +171,12 @@ private class NullCheckcastAwareOptimizationBasicInterpreter : OptimizationBasic } return super.unaryOperation(insn, value) } -} \ No newline at end of file + + override fun merge(v: BasicValue, w: BasicValue): BasicValue = + when { + v is TypedNullValue && w is TypedNullValue -> if (v.type == w.type) v else StrictBasicValue.NULL_VALUE + v is TypedNullValue -> super.merge(StrictBasicValue.NULL_VALUE, w) + w is TypedNullValue -> super.merge(v, StrictBasicValue.NULL_VALUE) + else -> super.merge(v, w) + } +} 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 197ba8b258e30..9fa7d04363309 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 @@ -10209,6 +10209,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt b/compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt new file mode 100644 index 0000000000000..160a13a74c046 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt @@ -0,0 +1,29 @@ +// WITH_STDLIB +// WITH_COROUTINES +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +fun someCondition() = true + +suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn { + it.resume(Unit) + COROUTINE_SUSPENDED +} + +fun expectString(x: String?) = x!! + +suspend fun foo(): String { + var x: String? = null + if (someCondition()) { + x = "OK" + } + suspendHere() + return expectString(x) +} + +fun box(): String { + var result = "fail" + suspend { result = foo() }.startCoroutine(EmptyContinuation) + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt b/compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt new file mode 100644 index 0000000000000..8321868f6bee7 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt @@ -0,0 +1,29 @@ +// WITH_STDLIB +// WITH_COROUTINES +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +fun someCondition() = false + +suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn { + it.resume(Unit) + COROUTINE_SUSPENDED +} + +fun expectString(x: String?) = x!! + +suspend fun foo(): String { + var x: String? = "OK" + if (someCondition()) { + x = null as String? + } + suspendHere() + return expectString(x) +} + +fun box(): String { + var result = "fail" + suspend { result = foo() }.startCoroutine(EmptyContinuation) + return result +} 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 96dfaec77438b..ee851fa474b07 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 @@ -10083,6 +10083,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() 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 e73c61aa03ff9..ff4663b5386ad 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 @@ -10209,6 +10209,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() 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 b2d8fe4528371..2539218f3e3d2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7934,6 +7934,16 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 79e68cd8feb9b..bffba527566f3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -7175,6 +7175,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 25c3ca07527f5..0e6931a770b64 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -7217,6 +7217,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 7965de9907e7a..0e8c84a0c6190 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -6256,6 +6256,16 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index ee988ab6927f5..bce406d69678f 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -8059,6 +8059,18 @@ public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt"); } + @Test + @TestMetadata("kt52311_nullOnLeft.kt") + public void testKt52311_nullOnLeft() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt"); + } + + @Test + @TestMetadata("kt52311_nullOnRight.kt") + public void testKt52311_nullOnRight() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception {