From fd50f306c94cf88e5315cbd92c12a71ab2e3696a Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 12 Mar 2024 16:22:20 +0100 Subject: [PATCH] [kotlin-dfa] Box/unbox result of try/catch (KTIJ-29010) GitOrigin-RevId: 40a12cce011a186e1cc730df757d5e5db2ecbef1 --- .../k2/codeinsight/inspections/dfa/KtControlFlowBuilder.kt | 5 ++++- .../idea/k2/inspections/tests/K2DataFlowInspectionTest.kt | 1 + .../kotlin/idea/inspections/dfa/KtControlFlowBuilder.kt | 5 ++++- .../kotlin/idea/inspections/KtDataFlowInspectionTest.kt | 1 + .../tests/testData/inspections/dfa/TryCatchReturnValue.kt | 4 ++++ 5 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/inspections/dfa/TryCatchReturnValue.kt diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/dfa/KtControlFlowBuilder.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/dfa/KtControlFlowBuilder.kt index ec4b1dd6df47..9f5ae0bfc110 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/dfa/KtControlFlowBuilder.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/dfa/KtControlFlowBuilder.kt @@ -1005,7 +1005,8 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi val finallyDescriptor = if (finallyBlock != null) EnterFinallyTrap(finallyBlock, finallyStart) else null finallyDescriptor?.let { trapTracker.pushTrap(it) } - val tempVar = flow.createTempVariable(DfType.TOP) + val kotlinType = statement.getKotlinType() + val tempVar = flow.createTempVariable(kotlinType.toDfType()) val sections = statement.catchClauses val clauses = LinkedHashMap() if (sections.isNotEmpty()) { @@ -1019,6 +1020,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi } processExpression(tryBlock) + addImplicitConversion(tryBlock, kotlinType) addInstruction(JvmAssignmentInstruction(null, tempVar)) val gotoEnd = createTransfer(statement, tryBlock, tempVar, true) @@ -1035,6 +1037,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi setOffset(offset) val catchBlock = section.catchBody processExpression(catchBlock) + addImplicitConversion(catchBlock, kotlinType) addInstruction(JvmAssignmentInstruction(null, tempVar)) controlTransfer(gotoEnd, singleFinally) } diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2DataFlowInspectionTest.kt b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2DataFlowInspectionTest.kt index 90ece280c41b..5a0ea3ea9b69 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2DataFlowInspectionTest.kt +++ b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2DataFlowInspectionTest.kt @@ -92,6 +92,7 @@ class K2DataFlowInspectionTest : AbstractK2InspectionTest() { fun testSuppressionsK2() = doTest() fun testTopLevelDeclaration() = doTest() fun testTryCatch() = doTest() + fun testTryCatchReturnValue() = doTest() fun testTryCatchInsideFinally() = doTest() fun testTryFinally() = doTest() fun testTypeCastK2() = doTest() diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/dfa/KtControlFlowBuilder.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/dfa/KtControlFlowBuilder.kt index 46bd430daafd..cf1fe6d71ff8 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/dfa/KtControlFlowBuilder.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/dfa/KtControlFlowBuilder.kt @@ -208,7 +208,8 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi val finallyDescriptor = if (finallyBlock != null) EnterFinallyTrap(finallyBlock, finallyStart) else null finallyDescriptor?.let { trapTracker.pushTrap(it) } - val tempVar = flow.createTempVariable(DfType.TOP) + val kotlinType = statement.getKotlinType() + val tempVar = flow.createTempVariable(kotlinType.toDfType()) val sections = statement.catchClauses val clauses = LinkedHashMap() if (sections.isNotEmpty()) { @@ -222,6 +223,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi } processExpression(tryBlock) + addImplicitConversion(tryBlock, kotlinType) addInstruction(JvmAssignmentInstruction(null, tempVar)) val gotoEnd = createTransfer(statement, tryBlock, tempVar, true) @@ -238,6 +240,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi setOffset(offset) val catchBlock = section.catchBody processExpression(catchBlock) + addImplicitConversion(catchBlock, kotlinType) addInstruction(JvmAssignmentInstruction(null, tempVar)) controlTransfer(gotoEnd, singleFinally) } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/KtDataFlowInspectionTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/KtDataFlowInspectionTest.kt index 91204a2be39f..08bf0c7451d2 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/KtDataFlowInspectionTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/KtDataFlowInspectionTest.kt @@ -93,6 +93,7 @@ class KtDataFlowInspectionTest : KotlinLightCodeInsightFixtureTestCase() { fun testSuppressions() = doTest() fun testTopLevelDeclaration() = doTest() fun testTryCatch() = doTest() + fun testTryCatchReturnValue() = doTest() fun testTryCatchInsideFinally() = doTest() fun testTryFinally() = doTest() fun testTypeCast() = doTest() diff --git a/plugins/kotlin/idea/tests/testData/inspections/dfa/TryCatchReturnValue.kt b/plugins/kotlin/idea/tests/testData/inspections/dfa/TryCatchReturnValue.kt new file mode 100644 index 000000000000..f59cfd9076ba --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspections/dfa/TryCatchReturnValue.kt @@ -0,0 +1,4 @@ +// WITH_STDLIB +fun main() { + if (1 == try { 1 } catch (e: Exception) { null }) {} +} \ No newline at end of file