FIR checker: report val reassignment
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
b128577508
commit
f1fa290d49
@@ -394,7 +394,7 @@ class LoopBlockExitNode(owner: ControlFlowGraph, override val fir: FirLoop, leve
|
||||
return visitor.visitLoopBlockExitNode(this, data)
|
||||
}
|
||||
}
|
||||
class LoopConditionEnterNode(owner: ControlFlowGraph, override val fir: FirExpression, level: Int, id: Int) : CFGNode<FirExpression>(owner, level, id), EnterNodeMarker {
|
||||
class LoopConditionEnterNode(owner: ControlFlowGraph, override val fir: FirExpression, val loop: FirLoop, level: Int, id: Int) : CFGNode<FirExpression>(owner, level, id), EnterNodeMarker {
|
||||
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
|
||||
return visitor.visitLoopConditionEnterNode(this, data)
|
||||
}
|
||||
|
||||
@@ -133,6 +133,11 @@ object NormalPath : EdgeLabel(label = null) {
|
||||
get() = true
|
||||
}
|
||||
|
||||
object LoopBackPath : EdgeLabel(label = null) {
|
||||
override val isNormal: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
object UncaughtExceptionPath : EdgeLabel(label = "onUncaughtException")
|
||||
|
||||
// TODO: Label `return`ing edge with this.
|
||||
|
||||
+10
-5
@@ -657,7 +657,7 @@ class ControlFlowGraphBuilder {
|
||||
}
|
||||
loopExitNodes.push(createLoopExitNode(loop))
|
||||
levelCounter++
|
||||
val conditionEnterNode = createLoopConditionEnterNode(loop.condition).also {
|
||||
val conditionEnterNode = createLoopConditionEnterNode(loop.condition, loop).also {
|
||||
addNewSimpleNode(it)
|
||||
// put conditional node twice so we can refer it after exit from loop block
|
||||
lastNodes.push(it)
|
||||
@@ -686,7 +686,7 @@ class ControlFlowGraphBuilder {
|
||||
if (lastNodes.isNotEmpty) {
|
||||
val conditionEnterNode = lastNodes.pop()
|
||||
require(conditionEnterNode is LoopConditionEnterNode) { loop.render() }
|
||||
addBackEdge(loopBlockExitNode, conditionEnterNode)
|
||||
addBackEdge(loopBlockExitNode, conditionEnterNode, label = LoopBackPath)
|
||||
}
|
||||
val loopExitNode = loopExitNodes.pop()
|
||||
loopExitNode.updateDeadStatus()
|
||||
@@ -714,7 +714,7 @@ class ControlFlowGraphBuilder {
|
||||
fun enterDoWhileLoopCondition(loop: FirLoop): Pair<LoopBlockExitNode, LoopConditionEnterNode> {
|
||||
levelCounter--
|
||||
val blockExitNode = createLoopBlockExitNode(loop).also { addNewSimpleNode(it) }
|
||||
val conditionEnterNode = createLoopConditionEnterNode(loop.condition).also { addNewSimpleNode(it) }
|
||||
val conditionEnterNode = createLoopConditionEnterNode(loop.condition, loop).also { addNewSimpleNode(it) }
|
||||
levelCounter++
|
||||
return blockExitNode to conditionEnterNode
|
||||
}
|
||||
@@ -727,7 +727,7 @@ class ControlFlowGraphBuilder {
|
||||
popAndAddEdge(conditionExitNode)
|
||||
val blockEnterNode = lastNodes.pop()
|
||||
require(blockEnterNode is LoopBlockEnterNode)
|
||||
addBackEdge(conditionExitNode, blockEnterNode, isDead = conditionBooleanValue == false)
|
||||
addBackEdge(conditionExitNode, blockEnterNode, isDead = conditionBooleanValue == false, label = LoopBackPath)
|
||||
val loopExit = loopExitNodes.pop()
|
||||
addEdge(conditionExitNode, loopExit, propagateDeadness = false, isDead = conditionBooleanValue == true)
|
||||
loopExit.updateDeadStatus()
|
||||
@@ -1261,7 +1261,12 @@ class ControlFlowGraphBuilder {
|
||||
popAndAddEdge(node, preferredKind)
|
||||
if (targetNode != null) {
|
||||
if (isBack) {
|
||||
addBackEdge(node, targetNode)
|
||||
if (targetNode is LoopEnterNode) {
|
||||
// `continue` to the loop header
|
||||
addBackEdge(node, targetNode, label = LoopBackPath)
|
||||
} else {
|
||||
addBackEdge(node, targetNode)
|
||||
}
|
||||
} else {
|
||||
addEdge(node, targetNode, propagateDeadness = false)
|
||||
}
|
||||
|
||||
+2
-2
@@ -113,8 +113,8 @@ fun ControlFlowGraphBuilder.createWhenBranchResultEnterNode(fir: FirWhenBranch):
|
||||
fun ControlFlowGraphBuilder.createLoopConditionExitNode(fir: FirExpression): LoopConditionExitNode =
|
||||
LoopConditionExitNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createLoopConditionEnterNode(fir: FirExpression): LoopConditionEnterNode =
|
||||
LoopConditionEnterNode(currentGraph, fir, levelCounter, createId())
|
||||
fun ControlFlowGraphBuilder.createLoopConditionEnterNode(fir: FirExpression, loop: FirLoop): LoopConditionEnterNode =
|
||||
LoopConditionEnterNode(currentGraph, fir, loop, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createLoopBlockEnterNode(fir: FirLoop): LoopBlockEnterNode =
|
||||
LoopBlockEnterNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
Reference in New Issue
Block a user