diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantGotoMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantGotoMethodTransformer.kt index 813693b1ac2..c005ef93f74 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantGotoMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantGotoMethodTransformer.kt @@ -82,17 +82,28 @@ class RedundantGotoMethodTransformer : MethodTransformer() { private fun rewriteLabelIfNeeded( jumpInsn: JumpInsnNode, - labelsToReplace: HashMap + labelsToReplace: Map ) { - val lastTargetLabel = getLastTargetJumpInsn(jumpInsn, labelsToReplace).label - if (lastTargetLabel != jumpInsn.label) { + val lastJumpInsn = getLastTargetJumpInsn(jumpInsn, labelsToReplace, mutableListOf()) + if (lastJumpInsn != null && lastJumpInsn != jumpInsn) { // Do not remove the old label because it can be used to define a local variable range. - jumpInsn.label = lastTargetLabel + jumpInsn.label = lastJumpInsn.label } } - private fun getLastTargetJumpInsn(jumpInsn: JumpInsnNode, labelsToReplace: HashMap): JumpInsnNode { - labelsToReplace[jumpInsn.label]?.let { return getLastTargetJumpInsn(it, labelsToReplace) } + private fun getLastTargetJumpInsn( + jumpInsn: JumpInsnNode, + labelsToReplace: Map, + alreadyVisited: MutableList + ): JumpInsnNode? { + labelsToReplace[jumpInsn.label]?.let { + if (alreadyVisited.contains(it)) { + // Cycle detected, do no apply goto optimization + return null + } + alreadyVisited.add(it) + return getLastTargetJumpInsn(it, labelsToReplace, alreadyVisited) + } return jumpInsn } } diff --git a/compiler/testData/codegen/bytecodeText/controlStructures/kt17110.kt b/compiler/testData/codegen/bytecodeText/controlStructures/kt17110.kt index a7f1f59b649..56cc1720425 100644 --- a/compiler/testData/codegen/bytecodeText/controlStructures/kt17110.kt +++ b/compiler/testData/codegen/bytecodeText/controlStructures/kt17110.kt @@ -12,10 +12,9 @@ fun test(x: Int, y: Int): String { return result } -fun box(): String { - if (test(9, 10) != "c") - return "Failures" - return "OK" +fun infiniteLoop() { + while(true) {} } -// 2 GOTO L7 \ No newline at end of file +// 2 GOTO L7 +// 1 GOTO L1 \ No newline at end of file