[K/N] Better handling of nested returns in RedundantCoercionsCleaner.kt

^KT-49356
This commit is contained in:
Pavel Kunyavskiy
2021-11-11 12:30:10 +03:00
committed by Space
parent 41547174a7
commit 523cb4b3e8
2 changed files with 27 additions and 1 deletions
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIA
import org.jetbrains.kotlin.backend.konan.getInlinedClassNative
import org.jetbrains.kotlin.backend.konan.ir.isBoxOrUnboxCall
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -161,6 +162,16 @@ internal class RedundantCoercionsCleaner(val context: Context) : FileLoweringPas
statements = statements,
inlineFunctionSymbol = inlineFunctionSymbol)
}
/*
* Visitor below requires being very careful when changing it.
* It heavily relies on implementation of fold and getFullExpression functions,
* in particular it uses fact, that parts of foldedReturnableBlockValues will be replaced
* simultaneously with IR.
*
* For example, this requires replacing ReturnableBlock symbols in separate pass,
* because it needs new return nodes to be created, which breaks changing it's content in
* foldedReturnableBlockValues.
*/
transformedReturnableBlock.transformChildrenVoid(object: IrElementTransformerVoid() {
override fun visitExpression(expression: IrExpression): IrExpression {
expression.transformChildrenVoid()
@@ -169,7 +180,8 @@ internal class RedundantCoercionsCleaner(val context: Context) : FileLoweringPas
}
return expression
}
})
transformedReturnableBlock.transformChildrenVoid(object: IrElementTransformerVoid() {
override fun visitReturn(expression: IrReturn): IrExpression {
expression.transformChildrenVoid(this)
return if (expression.returnTargetSymbol != oldSymbol)
@@ -33,3 +33,17 @@ inline fun foo2(): Int {
@Test fun runTest2() {
assertEquals(2, bar2())
}
// Test for https://youtrack.jetbrains.com/issue/KT-49356.
inline fun foo3(): Int {
return (return 3)
}
fun bar3(): Any {
return foo3()
}
@Test fun runTest3() {
assertEquals(3, bar3())
}