From df2e9e3797c65a92019408caa06870b97e87a4ad Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 6 Dec 2021 14:05:19 +0300 Subject: [PATCH] [FE 1.0] Correctly set USED_AS_EXPRESSION for unreachable when and if blocks ^KT-50028 Fixed --- .../runners/ir/Fir2IrTextTestGenerated.java | 6 +++++ .../cfg/ControlFlowInformationProviderImpl.kt | 26 +++++++++++++++---- .../returnsNothing/ifElse.kt | 5 +--- .../ir/irText/expressions/kt50028.fir.ir.txt | 21 +++++++++++++++ .../ir/irText/expressions/kt50028.fir.kt.txt | 12 +++++++++ .../ir/irText/expressions/kt50028.ir.txt | 24 +++++++++++++++++ .../testData/ir/irText/expressions/kt50028.kt | 17 ++++++++++++ .../ir/irText/expressions/kt50028.kt.txt | 18 +++++++++++++ .../test/runners/ir/IrTextTestGenerated.java | 6 +++++ .../kotlin/ir/KlibTextTestCaseGenerated.java | 5 ++++ 10 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/kt50028.fir.ir.txt create mode 100644 compiler/testData/ir/irText/expressions/kt50028.fir.kt.txt create mode 100644 compiler/testData/ir/irText/expressions/kt50028.ir.txt create mode 100644 compiler/testData/ir/irText/expressions/kt50028.kt create mode 100644 compiler/testData/ir/irText/expressions/kt50028.kt.txt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index 2ec288fadb9..07fa0ca96be 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -1658,6 +1658,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/kt49203.kt"); } + @Test + @TestMetadata("kt50028.kt") + public void testKt50028() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt50028.kt"); + } + @Test @TestMetadata("lambdaInCAO.kt") public void testLambdaInCAO() throws Exception { diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index a67a599fd47..1429c4ff3c1 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -812,17 +812,33 @@ class ControlFlowInformationProviderImpl private constructor( for (element in pseudocode.getValueElements(value)) { trace.record(USED_AS_EXPRESSION, element, isUsedAsExpression) trace.record(USED_AS_RESULT_OF_LAMBDA, element, isUsedAsResultOfLambda) - if (isUsedAsExpression && element is KtTryExpression) { - trace.record(USED_AS_EXPRESSION, element.tryBlock, true) - for (catchClause in element.catchClauses) { - val body = catchClause.catchBody ?: continue - trace.record(USED_AS_EXPRESSION, body, true) + if (isUsedAsExpression) { + when (element) { + is KtTryExpression -> { + element.tryBlock.recordUsedAsExpression() + for (catchClause in element.catchClauses) { + catchClause.catchBody?.recordUsedAsExpression() + } + } + is KtIfExpression -> { + (element.then as? KtBlockExpression)?.recordUsedAsExpression() + (element.`else` as? KtBlockExpression)?.recordUsedAsExpression() + } + is KtWhenExpression -> { + for (entry in element.entries) { + (entry.expression as? KtBlockExpression)?.recordUsedAsExpression() + } + } } } } } } + private fun KtExpression.recordUsedAsExpression() { + trace.record(USED_AS_EXPRESSION, this, true) + } + private fun checkForSuspendLambdaAndMarkParameters(pseudocode: Pseudocode) { for (instruction in pseudocode.instructionsIncludingDeadCode) { if (instruction is LocalFunctionDeclarationInstruction) { diff --git a/compiler/testData/codegen/box/controlStructures/returnsNothing/ifElse.kt b/compiler/testData/codegen/box/controlStructures/returnsNothing/ifElse.kt index 27edf40d44e..9637d51c389 100644 --- a/compiler/testData/codegen/box/controlStructures/returnsNothing/ifElse.kt +++ b/compiler/testData/codegen/box/controlStructures/returnsNothing/ifElse.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: STRANGE_IMPLICIT_CAST - fun kt49182(x: Boolean): String { return if (x) { return "O" @@ -23,4 +20,4 @@ fun box(): String { exit() } return a -} \ No newline at end of file +} diff --git a/compiler/testData/ir/irText/expressions/kt50028.fir.ir.txt b/compiler/testData/ir/irText/expressions/kt50028.fir.ir.txt new file mode 100644 index 00000000000..90b8cf23539 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt50028.fir.ir.txt @@ -0,0 +1,21 @@ +FILE fqName: fileName:/kt50028.kt + FUN name:test_1 visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test_1 (): kotlin.String declared in ' + WHEN type=kotlin.Nothing origin=WHEN + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: RETURN type=kotlin.Nothing from='public final fun test_1 (): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:test_2 visibility:public modality:FINAL <> (b:kotlin.Boolean) returnType:kotlin.Boolean + VALUE_PARAMETER name:b index:0 type:kotlin.Boolean + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test_2 (b: kotlin.Boolean): kotlin.Boolean declared in ' + WHEN type=kotlin.Boolean origin=IF + BRANCH + if: GET_VAR 'b: kotlin.Boolean declared in .test_2' type=kotlin.Boolean origin=null + then: CONST Boolean type=kotlin.Boolean value=true + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: THROW type=kotlin.Nothing + CONSTRUCTOR_CALL 'public constructor (message: kotlin.String) [primary] declared in kotlin.NotImplementedError' type=kotlin.NotImplementedError origin=null diff --git a/compiler/testData/ir/irText/expressions/kt50028.fir.kt.txt b/compiler/testData/ir/irText/expressions/kt50028.fir.kt.txt new file mode 100644 index 00000000000..5a8fc697c85 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt50028.fir.kt.txt @@ -0,0 +1,12 @@ +fun test_1(): String { + return when { + else -> return "" + } +} + +fun test_2(b: Boolean): Boolean { + return when { + b -> true + else -> throw NotImplementedError() + } +} diff --git a/compiler/testData/ir/irText/expressions/kt50028.ir.txt b/compiler/testData/ir/irText/expressions/kt50028.ir.txt new file mode 100644 index 00000000000..1f443f40fbe --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt50028.ir.txt @@ -0,0 +1,24 @@ +FILE fqName: fileName:/kt50028.kt + FUN name:test_1 visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test_1 (): kotlin.String declared in ' + WHEN type=kotlin.String origin=WHEN + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: BLOCK type=kotlin.Nothing origin=null + RETURN type=kotlin.Nothing from='public final fun test_1 (): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:test_2 visibility:public modality:FINAL <> (b:kotlin.Boolean) returnType:kotlin.Boolean + VALUE_PARAMETER name:b index:0 type:kotlin.Boolean + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test_2 (b: kotlin.Boolean): kotlin.Boolean declared in ' + WHEN type=kotlin.Boolean origin=IF + BRANCH + if: GET_VAR 'b: kotlin.Boolean declared in .test_2' type=kotlin.Boolean origin=null + then: BLOCK type=kotlin.Boolean origin=null + CONST Boolean type=kotlin.Boolean value=true + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: BLOCK type=kotlin.Nothing origin=null + THROW type=kotlin.Nothing + CONSTRUCTOR_CALL 'public constructor (message: kotlin.String) [primary] declared in kotlin.NotImplementedError' type=kotlin.NotImplementedError origin=null diff --git a/compiler/testData/ir/irText/expressions/kt50028.kt b/compiler/testData/ir/irText/expressions/kt50028.kt new file mode 100644 index 00000000000..79fe09a0a7d --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt50028.kt @@ -0,0 +1,17 @@ +// ISSUE: KT-50028 + +fun test_1(): String { + return when { + else -> { + return "" + } + } +} + +fun test_2(b: Boolean): Boolean { + return if (b) { + true + } else { + throw NotImplementedError() + } +} diff --git a/compiler/testData/ir/irText/expressions/kt50028.kt.txt b/compiler/testData/ir/irText/expressions/kt50028.kt.txt new file mode 100644 index 00000000000..0dd8f389176 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt50028.kt.txt @@ -0,0 +1,18 @@ +fun test_1(): String { + return when { + else -> { // BLOCK + return "" + } + } +} + +fun test_2(b: Boolean): Boolean { + return when { + b -> { // BLOCK + true + } + else -> { // BLOCK + throw NotImplementedError() + } + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index ba6f32346c6..44a75bb7321 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -1658,6 +1658,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/expressions/kt49203.kt"); } + @Test + @TestMetadata("kt50028.kt") + public void testKt50028() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt50028.kt"); + } + @Test @TestMetadata("lambdaInCAO.kt") public void testLambdaInCAO() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java index 52907a13a59..7fb5f5734d9 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java @@ -1247,6 +1247,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase { runTest("compiler/testData/ir/irText/expressions/kt49203.kt"); } + @TestMetadata("kt50028.kt") + public void testKt50028() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt50028.kt"); + } + @TestMetadata("lambdaInCAO.kt") public void testLambdaInCAO() throws Exception { runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");