[FIR] Fix data-flow after while loops

This commit is contained in:
simon.ogorodnik
2020-01-31 15:20:19 +03:00
committed by Mikhail Glukhikh
parent 91b432b4a1
commit 645602b675
15 changed files with 34 additions and 19 deletions
@@ -392,6 +392,19 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
// ----------------------------------- While Loop -----------------------------------
private fun exitCommonLoop(exitNode: LoopExitNode) {
val singlePreviousNode = exitNode.previousNodes.singleOrNull { !it.isDead }
if (singlePreviousNode is LoopConditionExitNode) {
val variable = variableStorage.getOrCreateVariable(singlePreviousNode.fir)
exitNode.flow = logicSystem.approveStatementsInsideFlow(
exitNode.flow,
variable eq false,
shouldForkFlow = false,
shouldRemoveSynthetics = true
)
}
}
fun enterWhileLoop(loop: FirLoop) {
val (loopEnterNode, loopConditionEnterNode) = graphBuilder.enterWhileLoop(loop)
loopEnterNode.mergeIncomingFlow()
@@ -407,7 +420,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
loopBlockEnterNode.flow,
conditionVariable eq true,
shouldForkFlow = false,
shouldRemoveSynthetics = true
shouldRemoveSynthetics = false
)
}
}
@@ -416,6 +429,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
val (blockExitNode, exitNode) = graphBuilder.exitWhileLoop(loop)
blockExitNode.mergeIncomingFlow()
exitNode.mergeIncomingFlow()
exitCommonLoop(exitNode)
}
// ----------------------------------- Do while Loop -----------------------------------
@@ -436,6 +450,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
val (loopConditionExitNode, loopExitNode) = graphBuilder.exitDoWhileLoop(loop)
loopConditionExitNode.mergeIncomingFlow()
loopExitNode.mergeIncomingFlow()
exitCommonLoop(loopExitNode)
}
// ----------------------------------- Try-catch-finally -----------------------------------