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 fcb282ab2a3..d09d7ea2295 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 ca6d8e329da..fc484910e84 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 class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT 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 00000000000..160a13a74c0 --- /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 00000000000..8321868f6be --- /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 5442e1c0659..da21eed07c0 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 @@ -10089,6 +10089,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { 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 5ff0ca6abe0..ed0985ff3bf 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 class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes 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 39a65f3e489..3248bc9567f 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7944,6 +7944,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes 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 8643afabeec..60900f644af 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 @@ -7181,6 +7181,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { 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 91bfd3121a5..494aae48c54 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 @@ -7223,6 +7223,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { 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 ca50f66fe6c..b2112ec07bb 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 @@ -6354,6 +6354,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest 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 b519076ecea..0c1f85f2542 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 @@ -8065,6 +8065,18 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest 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 {