From 373487ac9e306922a7cd3ce2dfb7208603f4f025 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Thu, 8 Aug 2024 09:52:02 -0700 Subject: [PATCH] [CFG] Fix var initialization check of nested lambdas and trys In deeply nested cases of a try-finally within a lambda, local var initialization checks can report false positives due to the recent capture-by-value changes meant for local val initialization checks. ^KT-70133 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ ...sticCompilerFE10TestDataTestGenerated.java | 6 +++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...ithLatestLanguageVersionTestGenerated.java | 6 +++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++ .../PropertyInitializationInfoCollector.kt | 7 --- .../nestedTryFinallyLambda.kt | 43 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++ 8 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 4c715d292203e..ad11e1a9c1a84 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -7872,6 +7872,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 0317f8fad776f..5971a268d38fe 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -7872,6 +7872,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 906143cb158d1..a13a8322f145e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -7866,6 +7866,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java index 547f59f15a8c1..63800fdf93532 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsWithLatestLanguageVersionTestGenerated.java @@ -7866,6 +7866,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index c754b87337b66..bb7d79b7af53a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -7872,6 +7872,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt index 65f7dde3bd6a3..ec8d444f4f717 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt @@ -93,13 +93,6 @@ class PropertyInitializationInfoCollector( data: PathAwarePropertyInitializationInfo ): PathAwarePropertyInitializationInfo { val result = super.visitEdge(from, to, metadata, data) - if (metadata.label == CapturedByValue) { - // Remove properties from data that are not captured by value. - val invalidProperties = data.flatMapTo(hashSetOf()) { it.value.keys }.filter { !it.isCapturedByValue } - return invalidProperties.fold(result) { filteredData, symbol -> - filteredData.removeRange(symbol) - } - } if (!metadata.kind.isBack) return result val declaredVariableSymbolsInCapturedScope = when { from is PostponedLambdaExitNode -> declaredVariablesInLoop[from.fir.anonymousFunction] diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt new file mode 100644 index 0000000000000..85730ea276719 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt @@ -0,0 +1,43 @@ +// FIR_IDENTICAL +fun invokeLater(x: () -> Unit) { + x() +} + +fun nestedFinallyAndLambda1() { + var x: String + invokeLater { + x = "" + invokeLater { + try { + } finally { + x.length + } + } + } +} + +fun nestedFinallyAndLambda2() { + var x: String + invokeLater { + x = "" + try { + } finally { + invokeLater { + x.length + } + } + } +} + +fun nestedFinallyAndLambda3() { + var x: String + try { + } finally { + invokeLater { + x = "" + invokeLater { + x.length + } + } + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 709607305fd3a..807059860df7b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -7872,6 +7872,12 @@ public void testNestedTryFinally() { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt"); } + @Test + @TestMetadata("nestedTryFinallyLambda.kt") + public void testNestedTryFinallyLambda() { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinallyLambda.kt"); + } + @Test @TestMetadata("nonLocalReturnUnreachable.kt") public void testNonLocalReturnUnreachable() {