Skip to content

Commit

Permalink
JVM: correctly merge typed null values
Browse files Browse the repository at this point in the history
1. merge(null of type A, null of type B) = null of unknown type;
2. merge(null of type A, something of type B) = merge(unknown null, B).

^KT-52311 Fixed
  • Loading branch information
pyos authored and ilmirus committed May 19, 2022
1 parent 54809ec commit c526ed7
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -171,4 +171,12 @@ private class NullCheckcastAwareOptimizationBasicInterpreter : OptimizationBasic
}
return super.unaryOperation(insn, value)
}
}

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)
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions compiler/testData/codegen/box/coroutines/kt52311_nullOnLeft.kt
Original file line number Diff line number Diff line change
@@ -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
}
29 changes: 29 additions & 0 deletions compiler/testData/codegen/box/coroutines/kt52311_nullOnRight.kt
Original file line number Diff line number Diff line change
@@ -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
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c526ed7

Please sign in to comment.