FIR checker: report val reassignment

This commit is contained in:
Jinseong Jeon
2021-02-19 00:51:16 -08:00
committed by Dmitriy Novozhilov
parent b128577508
commit f1fa290d49
66 changed files with 386 additions and 309 deletions
@@ -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.
@@ -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)
}
@@ -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())