diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index b8333b4347f..c4ee0650513 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -313,8 +313,10 @@ class Fir2IrVisitor( val irTarget = conversionScope.returnTarget(returnExpression, declarationStorage) return returnExpression.convertWithOffsets { startOffset, endOffset -> val result = returnExpression.result + // For implicit returns, use the expression endOffset to generate the expected line number for debugging. + val returnStartOffset = if (returnExpression.source?.kind == KtFakeSourceElementKind.ImplicitReturn) endOffset else startOffset IrReturnImpl( - startOffset, endOffset, irBuiltIns.nothingType, + returnStartOffset, endOffset, irBuiltIns.nothingType, when (irTarget) { is IrConstructor -> irTarget.symbol is IrSimpleFunction -> irTarget.symbol @@ -499,9 +501,9 @@ class Fir2IrVisitor( is FirBlock -> expression.convertToIrExpressionOrBlock( if (expression.source?.kind == KtFakeSourceElementKind.DesugaredForLoop) IrStatementOrigin.FOR_LOOP else null ) - is FirUnitExpression -> expression.convertWithOffsets { startOffset, endOffset -> + is FirUnitExpression -> expression.convertWithOffsets { _, endOffset -> IrGetObjectValueImpl( - startOffset, endOffset, irBuiltIns.unitType, this.irBuiltIns.unitClass + endOffset, endOffset, irBuiltIns.unitType, this.irBuiltIns.unitClass ) } else -> { @@ -625,6 +627,10 @@ class Fir2IrVisitor( return statements.convertToIrExpressionOrBlock(source, origin) } + private fun FirBlock.convertToIrBlock(origin: IrStatementOrigin? = null): IrExpression { + return statements.convertToIrBlock(source, origin) + } + private fun List.convertToIrExpressionOrBlock( source: KtSourceElement?, origin: IrStatementOrigin? = null @@ -637,6 +643,13 @@ class Fir2IrVisitor( return convertToIrExpression(firStatement) } } + return convertToIrBlock(source, origin) + } + + private fun List.convertToIrBlock( + source: KtSourceElement?, + origin: IrStatementOrigin? = null + ): IrExpression { val type = if (origin?.isLoop == true) irBuiltIns.unitType else @@ -940,7 +953,9 @@ class Fir2IrVisitor( startOffset, endOffset, tryExpression.typeRef.toIrType(), tryExpression.tryBlock.convertToIrExpressionOrBlock(), tryExpression.catches.map { it.accept(this, data) as IrCatch }, - tryExpression.finallyBlock?.convertToIrExpressionOrBlock() + // Always generate a block for the finally block. When leaving the finally block in the debugger for both + // Java and Kotlin there is a step on the end brace. For that to happen we need the block with that line number. + tryExpression.finallyBlock?.convertToIrBlock() ) } } diff --git a/compiler/testData/codegen/boxInline/smap/crossroutines.kt b/compiler/testData/codegen/boxInline/smap/crossroutines.kt index 24080f49f5d..454a938113e 100644 --- a/compiler/testData/codegen/boxInline/smap/crossroutines.kt +++ b/compiler/testData/codegen/boxInline/smap/crossroutines.kt @@ -1,6 +1,6 @@ // This test depends on line numbers // WITH_RUNTIME -// IGNORE_BACKEND_FIR: JVM_IR + // FILE: 1.kt package test diff --git a/compiler/testData/ir/irText/expressions/tryCatch.fir.ir.txt b/compiler/testData/ir/irText/expressions/tryCatch.fir.ir.txt index 668463370af..cc2565f261e 100644 --- a/compiler/testData/ir/irText/expressions/tryCatch.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/tryCatch.fir.ir.txt @@ -6,7 +6,8 @@ FILE fqName: fileName:/tryCatch.kt CATCH parameter=val e: kotlin.Throwable [val] declared in .test1 VAR name:e type:kotlin.Throwable [val] CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io.ConsoleKt' type=kotlin.Unit origin=null - finally: CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io.ConsoleKt' type=kotlin.Unit origin=null + finally: BLOCK type=kotlin.Unit origin=null + CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io.ConsoleKt' 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 ' diff --git a/compiler/testData/ir/irText/expressions/tryCatch.fir.kt.txt b/compiler/testData/ir/irText/expressions/tryCatch.fir.kt.txt index c8bd8877a5a..29b57084a5d 100644 --- a/compiler/testData/ir/irText/expressions/tryCatch.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/tryCatch.fir.kt.txt @@ -1,7 +1,9 @@ fun test1() { try println() catch (e: Throwable)println() - finally println() + finally { // BLOCK + println() + } } fun test2(): Int { @@ -18,3 +20,4 @@ fun test2(): Int { 555 } } +