Fixed bug in finally blocks lowering + test

Return type must be taken from the function
This commit is contained in:
Igor Chevdar
2018-06-29 12:21:08 +03:00
parent 6a07322f62
commit 11c4a2518d
3 changed files with 43 additions and 4 deletions
@@ -26,9 +26,6 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
@@ -38,6 +35,7 @@ import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -177,6 +175,14 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
return performHighLevelJump(tryScopes, 0, jump, startOffset, endOffset, value)
}
private val IrReturnTarget.returnType: IrType
get() = when (this) {
is IrConstructor -> context.irBuiltIns.unitType
is IrFunction -> returnType
is IrReturnableBlock -> type
else -> error("Unknown ReturnTarget: $this")
}
private fun performHighLevelJump(tryScopes: List<TryScope>,
index: Int,
jump: HighLevelJump,
@@ -188,7 +194,7 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
val currentTryScope = tryScopes[index]
currentTryScope.jumps.getOrPut(jump) {
val type = value.type
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
val symbol = getIrReturnableBlockSymbol(jump.toString(), type)
with(currentTryScope) {
irBuilder.run {
+5
View File
@@ -1893,6 +1893,11 @@ task finally11(type: RunKonanTest) {
source = "codegen/try/finally11.kt"
}
task finally_returnsDifferentTypes(type: RunKonanTest) {
goldValue = "zzz\n42\n"
source = "codegen/try/returnsDifferentTypes.kt"
}
task scope1(type: RunKonanTest) {
goldValue = "1\n"
source = "codegen/dataflow/scope1.kt"
@@ -0,0 +1,28 @@
package codegen.`try`.returnsDifferentTypes
import kotlin.test.*
class ReceiveChannel<out E>
inline fun <E, R> ReceiveChannel<E>.consume(block: ReceiveChannel<E>.() -> R): R {
try {
return block()
}
finally {
println("zzz")
}
}
inline fun <E> ReceiveChannel<E>.elementAtOrElse(index: Int, defaultValue: (Int) -> E): E =
consume {
if (index < 0)
return defaultValue(index)
return 42 as E
}
fun <E> ReceiveChannel<E>.elementAt(index: Int): E =
elementAtOrElse(index) { throw IndexOutOfBoundsException("qxx") }
@Test fun runTest() {
println(ReceiveChannel<Int>().elementAt(0))
}