[FIR] Unbound aliased variables in DFA more carefully
This commit is contained in:
+9
-3
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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<!>()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user