From bb242f022f367dbcd3b1002c4953f52c0fc41b69 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Thu, 18 Mar 2021 13:49:57 -0700 Subject: [PATCH] FIR renderer: avoid StackOverflow when rendering loop jump condition For example, ``` do { ... } while( when (...) { ... -> break } ) ``` That `break` condition is `when` expression, and while visiting its branch result, we will see the same `break` again. --- .../src/org/jetbrains/kotlin/fir/FirRenderer.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index a1c8577f85f..543d71543ed 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import java.util.* import kotlin.reflect.KClass fun FirElement.renderWithType(mode: FirRenderer.RenderMode = FirRenderer.RenderMode.Normal): String = buildString { @@ -780,12 +781,28 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM whileLoop.block.accept(this) } + private val loopJumpStack = Stack() + override fun visitLoopJump(loopJump: FirLoopJump) { + if (loopJumpStack.contains(loopJump)) { + // For example, + // do { + // ... + // } while( + // when (...) { + // ... -> break + // } + // ) + // That `break` condition is `when` expression, and while visiting its branch result, we will see the same `break` again. + return + } + loopJumpStack.push(loopJump) val target = loopJump.target val labeledElement = target.labeledElement print("@@@[") labeledElement.condition.accept(this) print("] ") + loopJumpStack.pop() } override fun visitBreakExpression(breakExpression: FirBreakExpression) {