FIR CFG: create TryMainBlockExitNode before visiting try main block
so that a node that returns Nothing inside try main block can route to the exit of try main block, instead of exit target for try directly.
This commit is contained in:
committed by
TeamCityServer
parent
7e5b562b33
commit
7a7114f896
+2
-2
@@ -718,8 +718,8 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
tryMainBlockEnterNode.mergeIncomingFlow(shouldForkFlow = true)
|
tryMainBlockEnterNode.mergeIncomingFlow(shouldForkFlow = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitTryMainBlock(tryExpression: FirTryExpression) {
|
fun exitTryMainBlock() {
|
||||||
graphBuilder.exitTryMainBlock(tryExpression).mergeIncomingFlow()
|
graphBuilder.exitTryMainBlock().mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enterCatchClause(catch: FirCatch) {
|
fun enterCatchClause(catch: FirCatch) {
|
||||||
|
|||||||
+6
-4
@@ -832,6 +832,9 @@ class ControlFlowGraphBuilder {
|
|||||||
val enterTryNodeBlock = createTryMainBlockEnterNode(tryExpression)
|
val enterTryNodeBlock = createTryMainBlockEnterNode(tryExpression)
|
||||||
addNewSimpleNode(enterTryNodeBlock)
|
addNewSimpleNode(enterTryNodeBlock)
|
||||||
|
|
||||||
|
val exitTryNodeBlock = createTryMainBlockExitNode(tryExpression)
|
||||||
|
tryMainExitNodes.push(exitTryNodeBlock)
|
||||||
|
|
||||||
for (catch in tryExpression.catches) {
|
for (catch in tryExpression.catches) {
|
||||||
val catchNode = createCatchClauseEnterNode(catch)
|
val catchNode = createCatchClauseEnterNode(catch)
|
||||||
catchNodeStorage.push(catchNode)
|
catchNodeStorage.push(catchNode)
|
||||||
@@ -850,10 +853,9 @@ class ControlFlowGraphBuilder {
|
|||||||
return enterTryExpressionNode to enterTryNodeBlock
|
return enterTryExpressionNode to enterTryNodeBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitTryMainBlock(tryExpression: FirTryExpression): TryMainBlockExitNode {
|
fun exitTryMainBlock(): TryMainBlockExitNode {
|
||||||
levelCounter--
|
levelCounter--
|
||||||
val node = createTryMainBlockExitNode(tryExpression)
|
val node = tryMainExitNodes.top()
|
||||||
tryMainExitNodes.push(node)
|
|
||||||
popAndAddEdge(node)
|
popAndAddEdge(node)
|
||||||
val finallyEnterNode = finallyEnterNodes.topOrNull()
|
val finallyEnterNode = finallyEnterNodes.topOrNull()
|
||||||
// NB: Check the level to avoid adding an edge to the finally block at an upper level.
|
// NB: Check the level to avoid adding an edge to the finally block at an upper level.
|
||||||
@@ -1266,7 +1268,7 @@ class ControlFlowGraphBuilder {
|
|||||||
tryExitNodes.top().fir.finallyBlock == null -> {
|
tryExitNodes.top().fir.finallyBlock == null -> {
|
||||||
// (3)... without finally ...(4)
|
// (3)... without finally ...(4)
|
||||||
// Either in try-main or catch.
|
// Either in try-main or catch.
|
||||||
if (tryExitNodes.size == tryMainExitNodes.size) {
|
if (tryMainExitNodes.top().followingNodes.isNotEmpty()) {
|
||||||
// (4)... in catch, i.e., re-throw.
|
// (4)... in catch, i.e., re-throw.
|
||||||
exitTargetsForTry.top()
|
exitTargetsForTry.top()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -144,7 +144,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
tryExpression.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
tryExpression.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||||
dataFlowAnalyzer.enterTryExpression(tryExpression)
|
dataFlowAnalyzer.enterTryExpression(tryExpression)
|
||||||
tryExpression.transformTryBlock(transformer, ResolutionMode.ContextDependent)
|
tryExpression.transformTryBlock(transformer, ResolutionMode.ContextDependent)
|
||||||
dataFlowAnalyzer.exitTryMainBlock(tryExpression)
|
dataFlowAnalyzer.exitTryMainBlock()
|
||||||
tryExpression.transformCatches(this, ResolutionMode.ContextDependent)
|
tryExpression.transformCatches(this, ResolutionMode.ContextDependent)
|
||||||
|
|
||||||
var callCompleted = false
|
var callCompleted = false
|
||||||
|
|||||||
Reference in New Issue
Block a user