KT-23931 Avoid infinite loop into RedundantGotoMethodTransformer

- Follow-up of 9fb0f59813 to avoid
infinite loop during redundant goto otpimization.

Fix of https://youtrack.jetbrains.com/issue/KT-23931
This commit is contained in:
Mikaël Peltier
2018-04-22 11:18:16 +02:00
committed by Stanislav Erokhin
parent 7daf44a806
commit b1ef670818
2 changed files with 21 additions and 11 deletions
@@ -82,17 +82,28 @@ class RedundantGotoMethodTransformer : MethodTransformer() {
private fun rewriteLabelIfNeeded( private fun rewriteLabelIfNeeded(
jumpInsn: JumpInsnNode, jumpInsn: JumpInsnNode,
labelsToReplace: HashMap<LabelNode, JumpInsnNode> labelsToReplace: Map<LabelNode, JumpInsnNode>
) { ) {
val lastTargetLabel = getLastTargetJumpInsn(jumpInsn, labelsToReplace).label val lastJumpInsn = getLastTargetJumpInsn(jumpInsn, labelsToReplace, mutableListOf())
if (lastTargetLabel != jumpInsn.label) { if (lastJumpInsn != null && lastJumpInsn != jumpInsn) {
// Do not remove the old label because it can be used to define a local variable range. // 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<LabelNode, JumpInsnNode>): JumpInsnNode { private fun getLastTargetJumpInsn(
labelsToReplace[jumpInsn.label]?.let { return getLastTargetJumpInsn(it, labelsToReplace) } jumpInsn: JumpInsnNode,
labelsToReplace: Map<LabelNode, JumpInsnNode>,
alreadyVisited: MutableList<JumpInsnNode>
): 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 return jumpInsn
} }
} }
@@ -12,10 +12,9 @@ fun test(x: Int, y: Int): String {
return result return result
} }
fun box(): String { fun infiniteLoop() {
if (test(9, 10) != "c") while(true) {}
return "Failures"
return "OK"
} }
// 2 GOTO L7 // 2 GOTO L7
// 1 GOTO L1