From 441be56a40fbbd2411efd36cff17751696fe080f Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 24 Apr 2017 12:23:49 +0300 Subject: [PATCH] During inlining, remove POP instructions popping inlined lambdas In cases like KT-17384, where 'break' or 'continue' happens in an argument to an inlined lambda call, fix-stack transformation sees corresponding ALOAD for lambda, and inserts corresponding POP instruction before jump. However, this ALOAD is later removed during inlining. So, we should also remove the related POP instructions. --- .../kotlin/codegen/inline/MethodInliner.java | 8 +++++- .../breakContinueInExpressions/kt17384.kt | 26 +++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 6 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 6 +++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java index 5f0a9a9cda4..47a0ef4b73e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.ClosureCodegen; import org.jetbrains.kotlin.codegen.StackValue; import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer; +import org.jetbrains.kotlin.codegen.optimization.fixStack.StackTransformationUtilsKt; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.utils.SmartList; import org.jetbrains.kotlin.utils.SmartSet; @@ -512,7 +513,12 @@ public class MethodInliner { ) ); } - + } + else if (cur.getOpcode() == Opcodes.POP) { + LambdaInfo lambda = getLambdaIfExists(MethodInlinerUtilKt.singleOrNullInsn(StackTransformationUtilsKt.top(frame))); + if (lambda != null) { + toDelete.add(cur); + } } } AbstractInsnNode prevNode = cur; diff --git a/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt new file mode 100644 index 00000000000..21aa85b6baa --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt @@ -0,0 +1,26 @@ +fun returnNullable(): String? = null + +inline fun Array.matchAll(fn: (String) -> Unit) { + for (string in this) { + fn(returnNullable() ?: continue) + } +} + +fun Array.matchAll2(fn: (String) -> Unit) { + matchAll(fn) +} + +inline fun Array.matchAll3(crossinline fn: (String) -> Unit) { + matchAll2 { fn(it) } +} + +fun test(a: Array) { + a.matchAll {} + a.matchAll2 {} + a.matchAll3 {} +} + +fun box(): String { + test(arrayOf("")) + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 8e13a38d2d1..92ccbccabd9 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -4630,6 +4630,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt17384.kt") + public void testKt17384() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt"); + doTest(fileName); + } + @TestMetadata("kt9022And.kt") public void testKt9022And() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 90280c4b93b..eaff3a5d561 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -4630,6 +4630,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt17384.kt") + public void testKt17384() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt"); + doTest(fileName); + } + @TestMetadata("kt9022And.kt") public void testKt9022And() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 5fedb7037f3..a6802e92750 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -4630,6 +4630,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt17384.kt") + public void testKt17384() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt"); + doTest(fileName); + } + @TestMetadata("kt9022And.kt") public void testKt9022And() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 57994e5c995..10f89ad7fe4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5339,6 +5339,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("kt17384.kt") + public void testKt17384() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt17384.kt"); + doTest(fileName); + } + @TestMetadata("kt9022And.kt") public void testKt9022And() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt");