[FIR] Unbound aliased variables in DFA more carefully

This commit is contained in:
Dmitriy Novozhilov
2020-01-21 17:42:55 +03:00
parent 2a23e14e2b
commit 384a094193
7 changed files with 15 additions and 9 deletions
@@ -610,10 +610,16 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
} }
private fun exitVariableInitialization(node: CFGNode<*>, initializer: FirExpression, variable: FirProperty, isVariableDeclaration: Boolean) { 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) { if (!isVariableDeclaration) {
node.flow.removeAllAboutVariable(propertyVariable) // Don't remove statements for variable under alias
variableStorage.unboundPossiblyAliasedVariable(variable.symbol) 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<SyntheticVariable>()?.let { initializerVariable -> variableStorage[initializer]?.safeAs<SyntheticVariable>()?.let { initializerVariable ->
@@ -41,7 +41,7 @@ fun f(a: SomeClass?) {
if (aa as? SomeSubClass != null) { if (aa as? SomeSubClass != null) {
aa = null aa = null
// 'aa' cannot be cast to SomeSubClass // 'aa' cannot be cast to SomeSubClass
aa.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() aa.<!UNRESOLVED_REFERENCE!>hashCode<!>()
aa.<!UNRESOLVED_REFERENCE!>foo<!> aa.<!UNRESOLVED_REFERENCE!>foo<!>
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!> (aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(aa as SomeSubClass).foo (aa as SomeSubClass).foo
@@ -17,7 +17,7 @@ fun foo(arg: Int?) {
var z = arg var z = arg
z = z?.let { 42 } z = z?.let { 42 }
if (z != null) { if (z != null) {
arg.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() arg.hashCode()
} }
} }
@@ -9,5 +9,5 @@ fun foo(arg: Int?) {
} }
if (x != null) x = 42 if (x != null) x = 42
// Unsafe because of lambda // Unsafe because of lambda
x.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() x.<!UNRESOLVED_REFERENCE!>hashCode<!>()
} }
@@ -15,6 +15,6 @@ fun foo(arg: Int?) {
var z = arg var z = arg
z = z?.let { 42 } z = z?.let { 42 }
if (z != null) { if (z != null) {
arg.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() arg.hashCode()
} }
} }
@@ -23,7 +23,7 @@ fun bar(s: String?) {
val hashCode = ss?.hashCode() val hashCode = ss?.hashCode()
ss = null ss = null
if (hashCode != null) { if (hashCode != null) {
ss.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() ss.<!UNRESOLVED_REFERENCE!>hashCode<!>()
} }
} }
@@ -2,7 +2,7 @@
fun foo(arg: Int?): Int { fun foo(arg: Int?): Int {
var i = arg var i = arg
if (i != null && i++ == 5) { if (i != null && i++ == 5) {
return i<!INAPPLICABLE_CANDIDATE!>--<!> + i return i-- + i
} }
return 0 return 0
} }