[FIR] Fix false positive "return required" for if/else with inlined return in branch

^KT-49289 Fixed
This commit is contained in:
Ivan Kochurkin
2021-10-25 18:44:09 +03:00
committed by TeamCityServer
parent 5b10396f48
commit 744191099c
7 changed files with 55 additions and 3 deletions
@@ -15843,6 +15843,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/inline/inlineReified.kt");
}
@Test
@TestMetadata("inlinedReturnInBranch.kt")
public void testInlinedReturnInBranch() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/inlinedReturnInBranch.kt");
}
@Test
@TestMetadata("invoke.kt")
public void testInvoke() throws Exception {
@@ -15843,6 +15843,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inline/inlineReified.kt");
}
@Test
@TestMetadata("inlinedReturnInBranch.kt")
public void testInlinedReturnInBranch() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/inlinedReturnInBranch.kt");
}
@Test
@TestMetadata("invoke.kt")
public void testInvoke() throws Exception {
@@ -15843,6 +15843,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inline/inlineReified.kt");
}
@Test
@TestMetadata("inlinedReturnInBranch.kt")
public void testInlinedReturnInBranch() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/inlinedReturnInBranch.kt");
}
@Test
@TestMetadata("invoke.kt")
public void testInvoke() throws Exception {
@@ -641,6 +641,7 @@ class ControlFlowGraphBuilder {
addNewSimpleNode(node)
whenExitNodes.push(createWhenExitNode(whenExpression))
whenBranchIndices.push(whenExpression.branches.mapIndexed { index, branch -> branch to index }.toMap())
notCompletedFunctionCalls.push(mutableListOf())
levelCounter++
return node
}
@@ -676,6 +677,7 @@ class ControlFlowGraphBuilder {
val whenExitNode = whenExitNodes.pop()
// exit from last condition node still on stack
// we should remove it
notCompletedFunctionCalls.pop().forEach(::completeFunctionCall)
val lastWhenConditionExit = lastNodes.pop()
val syntheticElseBranchNode = if (!whenExpression.isProperlyExhaustive) {
createWhenSyntheticElseBranchNode(whenExpression).apply {
@@ -985,7 +987,7 @@ class ControlFlowGraphBuilder {
catchNodeStorages.pop()
val catchExitNodes = catchExitNodeStorages.pop()
val tryMainExitNode = tryMainExitNodes.pop()
notCompletedFunctionCalls.pop().forEach(::completeFunctionCall)
val node = tryExitNodes.pop()
@@ -1396,14 +1398,15 @@ class ControlFlowGraphBuilder {
tryExitNodes.top().fir.finallyBlock == null -> {
// (3)... without finally ...(4)
// Either in try-main or catch.
if (tryMainExitNodes.top().followingNodes.isNotEmpty()) {
val tryMainExitNode = tryMainExitNodes.top()
if (tryMainExitNode.followingNodes.isNotEmpty()) {
// (4)... in catch, i.e., re-throw.
exitTargetsForTry.top()
} else {
// (4)... in try-main. Route to exit of try main block.
// We already have edges from the exit of try main block to each catch clause.
// This edge makes the remaining part of try main block, e.g., following `when` branches, marked as dead.
tryMainExitNodes.top()
tryMainExitNode
}
}
// (3)... within finally.
@@ -0,0 +1,20 @@
// FIR_IDENTICAL
// https://youtrack.jetbrains.com/issue/KT-49289
inline fun <T> myRun(f: () -> T): T = f()
fun foo(): Int {
myRun {
return 24
}
}
fun bar(arg: Boolean): Int {
if (arg) {
return 42
} else {
myRun {
return 24
}
}
}
@@ -0,0 +1,5 @@
package
public fun bar(/*0*/ arg: kotlin.Boolean): kotlin.Int
public fun foo(): kotlin.Int
public inline fun </*0*/ T> myRun(/*0*/ f: () -> T): T
@@ -15849,6 +15849,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inline/inlineReified.kt");
}
@Test
@TestMetadata("inlinedReturnInBranch.kt")
public void testInlinedReturnInBranch() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/inlinedReturnInBranch.kt");
}
@Test
@TestMetadata("invoke.kt")
public void testInvoke() throws Exception {