Fir2Ir: generate 'finally' block always with Unit type

This is important for IR lowerings like PolymorphicSignatureLowering
which are very sensitive about the correct types of expressions and
placement of coercions to Unit (KT-59218).

A boolean parameter to `insertImplicitCasts` is not the best solution to
ensure that coercion to Unit is added. The best solution would be to fix
the TODO and generate coercion to the block's type for the last
statement. But that will affect many other places and will need to be
done separately => KT-59781.

Code in IrInterpreter is uncommented to fix the FIR test
`compiler/testData/ir/interpreter/exceptions/tryFinally.kt`; otherwise
evaluation of the function `returnTryFinally` there crashes with
"NoSuchElementException: ArrayDeque is empty". No idea why this test
didn't fail for K1 though, since the created IR is exactly the same.

For some unknown reason this breaks WASM backend with K2, but not with
K1 => KT-59800.
This commit is contained in:
Alexander Udalov
2023-06-29 17:59:50 +02:00
committed by Space Team
parent 79fa2b6db0
commit 69059362b8
23 changed files with 119 additions and 69 deletions
+2
View File
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: WASM
// ^ KT-59800 K2 + Wasm: test failure after changing `finally` block generation
fun test1() : Boolean {
try {
@@ -0,0 +1,9 @@
fun check(value: Any?) {
if (value != Unit) throw AssertionError("Fail: $value")
}
fun box(): String {
val x = 10
check(try { } catch (e: Exception) { } finally { x })
return "OK"
}
@@ -1,27 +0,0 @@
FILE fqName:<root> fileName:/tryCatch.kt
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TRY type=kotlin.Unit
try: BLOCK type=kotlin.Unit origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
CATCH parameter=val e: kotlin.Throwable declared in <root>.test1
VAR CATCH_PARAMETER name:e type:kotlin.Throwable [val]
BLOCK type=kotlin.Unit origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
finally: BLOCK type=kotlin.Unit origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2 (): kotlin.Int declared in <root>'
TRY type=kotlin.Int
try: BLOCK type=kotlin.Int origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
CONST Int type=kotlin.Int value=42
CATCH parameter=val e: kotlin.Throwable declared in <root>.test2
VAR CATCH_PARAMETER name:e type:kotlin.Throwable [val]
BLOCK type=kotlin.Int origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
CONST Int type=kotlin.Int value=24
finally: BLOCK type=kotlin.Int origin=null
CALL 'public final fun println (): kotlin.Unit declared in kotlin.io' type=kotlin.Unit origin=null
CONST Int type=kotlin.Int value=555
@@ -1,27 +0,0 @@
fun test1() {
try { // BLOCK
println()
}
catch (e: Throwable){ // BLOCK
println()
}
finally { // BLOCK
println()
}
}
fun test2(): Int {
return try { // BLOCK
println()
42
}
catch (e: Throwable){ // BLOCK
println()
24
}
finally { // BLOCK
println()
555
}
}
+1
View File
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// WITH_STDLIB
fun test1() {