From 384a09419397329165eadd53f2cfdbcd052eecf6 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 21 Jan 2020 17:42:55 +0300 Subject: [PATCH] [FIR] Unbound aliased variables in DFA more carefully --- .../kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt | 12 +++++++++--- .../tests/smartCasts/castchecks/variables.fir.kt | 2 +- .../diagnostics/tests/smartCasts/level_1_0.fir.kt | 2 +- .../smartCasts/ownerDeclaresBothModifies.fir.kt | 2 +- .../smartCasts/varnotnull/boundInitializer.fir.kt | 2 +- .../varnotnull/boundInitializerWrong.fir.kt | 2 +- .../smartCasts/varnotnull/plusplusMinusminus.fir.kt | 2 +- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 6dcf55b728f..f8d4cc17d39 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -610,10 +610,16 @@ abstract class FirDataFlowAnalyzer( } private fun exitVariableInitialization(node: CFGNode<*>, initializer: FirExpression, variable: FirProperty, isVariableDeclaration: Boolean) { - val propertyVariable = variableStorage.getOrCreateRealVariable(variable.symbol, variable) + var propertyVariable = variableStorage.getOrCreateRealVariable(variable.symbol, variable) if (!isVariableDeclaration) { - node.flow.removeAllAboutVariable(propertyVariable) - variableStorage.unboundPossiblyAliasedVariable(variable.symbol) + // Don't remove statements for variable under alias + if (propertyVariable.identifier.symbol == variable.symbol) { + node.flow.removeAllAboutVariable(propertyVariable) + } else { + variableStorage.unboundPossiblyAliasedVariable(variable.symbol) + // We should create new dataFlowVariable for local variable without alias + propertyVariable = variableStorage.getOrCreateRealVariable(variable.symbol, variable) + } } variableStorage[initializer]?.safeAs()?.let { initializerVariable -> diff --git a/compiler/testData/diagnostics/tests/smartCasts/castchecks/variables.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/castchecks/variables.fir.kt index dac9cd9c46c..c15a3857cbd 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/castchecks/variables.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/castchecks/variables.fir.kt @@ -41,7 +41,7 @@ fun f(a: SomeClass?) { if (aa as? SomeSubClass != null) { aa = null // 'aa' cannot be cast to SomeSubClass - aa.hashCode() + aa.hashCode() aa.foo (aa as? SomeSubClass).foo (aa as SomeSubClass).foo diff --git a/compiler/testData/diagnostics/tests/smartCasts/level_1_0.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/level_1_0.fir.kt index e1328025d00..346542ace59 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/level_1_0.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/level_1_0.fir.kt @@ -17,7 +17,7 @@ fun foo(arg: Int?) { var z = arg z = z?.let { 42 } if (z != null) { - arg.hashCode() + arg.hashCode() } } diff --git a/compiler/testData/diagnostics/tests/smartCasts/ownerDeclaresBothModifies.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/ownerDeclaresBothModifies.fir.kt index 9059f8bb307..e6df621d176 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/ownerDeclaresBothModifies.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/ownerDeclaresBothModifies.fir.kt @@ -9,5 +9,5 @@ fun foo(arg: Int?) { } if (x != null) x = 42 // Unsafe because of lambda - x.hashCode() + x.hashCode() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializer.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializer.fir.kt index ec71bd58969..60589b26bb1 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializer.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializer.fir.kt @@ -15,6 +15,6 @@ fun foo(arg: Int?) { var z = arg z = z?.let { 42 } if (z != null) { - arg.hashCode() + arg.hashCode() } } diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializerWrong.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializerWrong.fir.kt index 55fdd3cde55..1f3539b9756 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializerWrong.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/boundInitializerWrong.fir.kt @@ -23,7 +23,7 @@ fun bar(s: String?) { val hashCode = ss?.hashCode() ss = null if (hashCode != null) { - ss.hashCode() + ss.hashCode() } } diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt index 2dbd452a6bd..dc2a9386d1f 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt @@ -2,7 +2,7 @@ fun foo(arg: Int?): Int { var i = arg if (i != null && i++ == 5) { - return i-- + i + return i-- + i } return 0 }