From ecd20b13486fc889cfad52f1f5e27513308d469b Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 28 Jun 2023 17:06:18 +0200 Subject: [PATCH] [JVM_IR] Properly handle inlined local var located in regenerated object #KT-58778 --- ...irLightTreeLocalVariableTestGenerated.java | 12 ++ .../FirPsiLocalVariableTestGenerated.java | 12 ++ .../backend/jvm/codegen/ExpressionCodegen.kt | 20 ++-- ...liningLocalVariablesAfterInlineLowering.kt | 8 ++ .../tryFinally/chained/intReturnComplex4.kt | 2 - .../debug/localVariables/inlineFunInObject.kt | 103 ++++++++++++++++++ .../debug/localVariables/lambdaInObject.kt | 66 +++++++++++ ...lVariableBytecodeInlinerTestGenerated.java | 12 ++ ...IrLocalVariableIrInlinerTestGenerated.java | 12 ++ .../codegen/LocalVariableTestGenerated.java | 12 ++ .../ir/IrJsLocalVariableTestGenerated.java | 12 ++ 11 files changed, 259 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/debug/localVariables/inlineFunInObject.kt create mode 100644 compiler/testData/debug/localVariables/lambdaInObject.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeLocalVariableTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeLocalVariableTestGenerated.java index 4a9d0eda0b6..f46eee8b5ff 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeLocalVariableTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeLocalVariableTestGenerated.java @@ -67,6 +67,12 @@ public class FirLightTreeLocalVariableTestGenerated extends AbstractFirLightTree runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class FirLightTreeLocalVariableTestGenerated extends AbstractFirLightTree runTest("compiler/testData/debug/localVariables/jvmOverloads.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiLocalVariableTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiLocalVariableTestGenerated.java index bb896bef872..98e9c98f989 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiLocalVariableTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiLocalVariableTestGenerated.java @@ -67,6 +67,12 @@ public class FirPsiLocalVariableTestGenerated extends AbstractFirPsiLocalVariabl runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class FirPsiLocalVariableTestGenerated extends AbstractFirPsiLocalVariabl runTest("compiler/testData/debug/localVariables/jvmOverloads.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception { diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index f3451bd9cbe..ab1aae8ce77 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -422,8 +422,16 @@ class ExpressionCodegen( } } - if (expression is IrInlinedFunctionBlock && expression.isFunctionInlining()) { - markLineNumberAfterInlineIfNeeded(isInsideCondition) + if (expression is IrInlinedFunctionBlock) { + // This block must be executed after `writeLocalVariablesInTable` + if (expression.isFunctionInlining()) { + val callLineNumber = lineNumberMapper.getLineNumberForOffset(expression.inlineCall.startOffset) + // takeUnless is required to avoid markLineNumberAfterInlineIfNeeded for inline only + lastLineNumber = callLineNumber.takeUnless { noLineNumberScope } ?: -1 + markLineNumberAfterInlineIfNeeded(isInsideCondition) + } else { + lineNumberMapper.setUpAdditionalLineNumbersAfterLambdaInlining(expression) + } } if (isSynthesizedInitBlock) { @@ -482,7 +490,6 @@ class ExpressionCodegen( private fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: BlockInfo): PromisedValue { val inlineCall = inlinedBlock.inlineCall val callee = inlinedBlock.inlineDeclaration as? IrFunction - val callLineNumber = lineNumberMapper.getLineNumberForOffset(inlineCall.startOffset) // 1. Evaluate NON DEFAULT arguments from inline function call inlinedBlock.getNonDefaultAdditionalStatementsFromInlinedBlock().forEach { exp -> @@ -539,13 +546,6 @@ class ExpressionCodegen( lineNumberMapper.dropCurrentSmap() - if (inlinedBlock.isLambdaInlining()) { - lineNumberMapper.setUpAdditionalLineNumbersAfterLambdaInlining(inlinedBlock) - } else { - // takeUnless is required to avoid markLineNumberAfterInlineIfNeeded for inline only - lastLineNumber = callLineNumber.takeUnless { noLineNumberScope } ?: -1 - } - return result } } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeInliningLocalVariablesAfterInlineLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeInliningLocalVariablesAfterInlineLowering.kt index 9e21191d827..13efe86733d 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeInliningLocalVariablesAfterInlineLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeInliningLocalVariablesAfterInlineLowering.kt @@ -123,6 +123,14 @@ private class LocalVariablesProcessor : IrElementVisitor Unit) { + object { + fun baz(param: Int) { + val a = 1 + inlineCall { + val f = 6 + } + } + }.baz(5) +} + +inline fun bar(crossinline block: () -> Unit) { + object { + fun baz(param: Int) { + val b = 2 + block() + inlineCall { + val g = 7 + } + } + }.baz(6) +} + +inline fun inlineCall(block: () -> Unit) { + val e = 5 + block() +} + +fun box() { + foo() { + val c = 3 + } + + bar() { + val d = 4 + } +} + +// EXPECTATIONS JVM JVM_IR +// test.kt:31 box: +// test.kt:3 box: $i$f$foo:int=0:int +// test.kt:3 : +// test.kt:10 box: $i$f$foo:int=0:int +// test.kt:5 baz: param:int=5:int +// test.kt:6 baz: param:int=5:int, a:int=1:int +// test.kt:26 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int +// test.kt:27 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:7 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$foo$1$baz$1:int=0:int +// EXPECTATIONS JVM_IR +// test.kt:8 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$foo$1$baz$1:int=0:int, f:int=6:int +// EXPECTATIONS JVM +// test.kt:8 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$foo$1$baz$1:int=0:int +// EXPECTATIONS JVM JVM_IR +// test.kt:27 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:28 baz: param:int=5:int, a:int=1:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:9 baz: param:int=5:int, a:int=1:int +// test.kt:11 box: $i$f$foo:int=0:int +// test.kt:35 box: +// test.kt:14 box: $i$f$bar:int=0:int +// test.kt:14 : +// test.kt:22 box: $i$f$bar:int=0:int +// test.kt:16 baz: param:int=6:int +// test.kt:17 baz: param:int=6:int, b:int=2:int +// test.kt:36 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int +// EXPECTATIONS JVM_IR +// test.kt:37 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int, d:int=4:int +// EXPECTATIONS JVM +// test.kt:37 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int +// EXPECTATIONS JVM JVM_IR +// test.kt:17 baz: param:int=6:int, b:int=2:int +// test.kt:18 baz: param:int=6:int, b:int=2:int +// test.kt:26 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int +// test.kt:27 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:19 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$bar$1$baz$1:int=0:int +// EXPECTATIONS JVM_IR +// test.kt:20 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$bar$1$baz$1:int=0:int, g:int=7:int +// EXPECTATIONS JVM +// test.kt:20 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int, $i$a$-inlineCall-TestKt$bar$1$baz$1:int=0:int +// EXPECTATIONS JVM JVM_IR +// test.kt:27 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:28 baz: param:int=6:int, b:int=2:int, $i$f$inlineCall:int=0:int, e$iv:int=5:int +// test.kt:21 baz: param:int=6:int, b:int=2:int +// test.kt:23 box: $i$f$bar:int=0:int +// test.kt:38 box: + +// EXPECTATIONS JS_IR +// test.kt:10 box: +// test.kt:3 : +// test.kt:10 box: +// test.kt:5 baz: param=5:number +// test.kt:26 baz: param=5:number, a=1:number +// test.kt:7 baz: param=5:number, a=1:number, e=5:number +// test.kt:9 baz: param=5:number, a=1:number, e=5:number, f=6:number +// test.kt:22 box: +// test.kt:14 : +// test.kt:22 box: +// test.kt:16 baz: param=6:number +// test.kt:36 baz: param=6:number, b=2:number +// test.kt:26 baz: param=6:number, b=2:number, d=4:number +// test.kt:19 baz: param=6:number, b=2:number, d=4:number, e=5:number +// test.kt:21 baz: param=6:number, b=2:number, d=4:number, e=5:number, g=7:number +// test.kt:38 box: diff --git a/compiler/testData/debug/localVariables/lambdaInObject.kt b/compiler/testData/debug/localVariables/lambdaInObject.kt new file mode 100644 index 00000000000..7dedeb9cc9d --- /dev/null +++ b/compiler/testData/debug/localVariables/lambdaInObject.kt @@ -0,0 +1,66 @@ +// FILE: test.kt +inline fun foo(block: () -> Unit) { + object { + fun baz(param: Int) { + val a = 1 + } + }.baz(5) +} + +inline fun bar(crossinline block: () -> Unit) { + object { + fun baz(param: Int) { + val b = 2 + block() + } + }.baz(6) +} + +fun box() { + foo() { + val c = 3 + } + + bar() { + val d = 4 + } +} + +// EXPECTATIONS JVM JVM_IR +// test.kt:20 box: +// test.kt:3 box: $i$f$foo:int=0:int +// test.kt:3 : +// test.kt:7 box: $i$f$foo:int=0:int +// test.kt:5 baz: param:int=5:int +// test.kt:6 baz: param:int=5:int, a:int=1:int +// test.kt:8 box: $i$f$foo:int=0:int +// test.kt:24 box: +// test.kt:11 box: $i$f$bar:int=0:int +// test.kt:11 : +// test.kt:16 box: $i$f$bar:int=0:int +// test.kt:13 baz: param:int=6:int +// test.kt:14 baz: param:int=6:int, b:int=2:int +// test.kt:25 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int +// EXPECTATIONS JVM_IR +// test.kt:26 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int, d:int=4:int +// EXPECTATIONS JVM +// test.kt:26 baz: param:int=6:int, b:int=2:int, $i$a$-bar-TestKt$box$2:int=0:int +// EXPECTATIONS JVM JVM_IR +// test.kt:14 baz: param:int=6:int, b:int=2:int +// test.kt:15 baz: param:int=6:int, b:int=2:int +// test.kt:17 box: $i$f$bar:int=0:int +// test.kt:27 box: + +// EXPECTATIONS JS_IR +// test.kt:7 box: +// test.kt:3 : +// test.kt:7 box: +// test.kt:5 baz: param=5:number +// test.kt:6 baz: param=5:number, a=1:number +// test.kt:16 box: +// test.kt:11 : +// test.kt:16 box: +// test.kt:13 baz: param=6:number +// test.kt:25 baz: param=6:number, b=2:number +// test.kt:15 baz: param=6:number, b=2:number, d=4:number +// test.kt:27 box: diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableBytecodeInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableBytecodeInlinerTestGenerated.java index e027f83dd82..32f86fee498 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableBytecodeInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableBytecodeInlinerTestGenerated.java @@ -67,6 +67,12 @@ public class IrLocalVariableBytecodeInlinerTestGenerated extends AbstractIrLocal runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class IrLocalVariableBytecodeInlinerTestGenerated extends AbstractIrLocal runTest("compiler/testData/debug/localVariables/jvmOverloads.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableIrInlinerTestGenerated.java index 5cbea4b291e..c8bf74848f4 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrLocalVariableIrInlinerTestGenerated.java @@ -67,6 +67,12 @@ public class IrLocalVariableIrInlinerTestGenerated extends AbstractIrLocalVariab runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class IrLocalVariableIrInlinerTestGenerated extends AbstractIrLocalVariab runTest("compiler/testData/debug/localVariables/jvmOverloads.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/LocalVariableTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/LocalVariableTestGenerated.java index 48e4330b4dd..dd8d0bca6cb 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/LocalVariableTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/LocalVariableTestGenerated.java @@ -67,6 +67,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/jvmOverloads.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsLocalVariableTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsLocalVariableTestGenerated.java index 3bb3f499982..9048bb97674 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsLocalVariableTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsLocalVariableTestGenerated.java @@ -67,6 +67,12 @@ public class IrJsLocalVariableTestGenerated extends AbstractIrJsLocalVariableTes runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt"); } + @Test + @TestMetadata("inlineFunInObject.kt") + public void testInlineFunInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/inlineFunInObject.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -79,6 +85,12 @@ public class IrJsLocalVariableTestGenerated extends AbstractIrJsLocalVariableTes runTest("compiler/testData/debug/localVariables/jsCode.kt"); } + @Test + @TestMetadata("lambdaInObject.kt") + public void testLambdaInObject() throws Exception { + runTest("compiler/testData/debug/localVariables/lambdaInObject.kt"); + } + @Test @TestMetadata("lambdaWithLambdaParameter.kt") public void testLambdaWithLambdaParameter() throws Exception {