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:
committed by
Stanislav Erokhin
parent
7daf44a806
commit
b1ef670818
+17
-6
@@ -82,17 +82,28 @@ class RedundantGotoMethodTransformer : MethodTransformer() {
|
||||
|
||||
private fun rewriteLabelIfNeeded(
|
||||
jumpInsn: JumpInsnNode,
|
||||
labelsToReplace: HashMap<LabelNode, JumpInsnNode>
|
||||
labelsToReplace: Map<LabelNode, JumpInsnNode>
|
||||
) {
|
||||
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<LabelNode, JumpInsnNode>): JumpInsnNode {
|
||||
labelsToReplace[jumpInsn.label]?.let { return getLastTargetJumpInsn(it, labelsToReplace) }
|
||||
private fun getLastTargetJumpInsn(
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// 2 GOTO L7
|
||||
// 1 GOTO L1
|
||||
Reference in New Issue
Block a user