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:
committed by
Space Team
parent
79fa2b6db0
commit
69059362b8
@@ -1,3 +1,5 @@
|
||||
// IGNORE_BACKEND_K2: WASM
|
||||
// ^ KT-59800 K2 + Wasm: test failure after changing `finally` block generation
|
||||
|
||||
fun test1() : Boolean {
|
||||
try {
|
||||
|
||||
Vendored
+9
@@ -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,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
|
||||
fun test1() {
|
||||
|
||||
Reference in New Issue
Block a user