c7272f6986
Currently DFA does not set "definitely equal to null" for access to variables that got assigned `null`. For example, FIR should mark the following line as SENSELESS_COMPARISON due to `s = null` above. https://github.com/JetBrains/kotlin/blob/d1531f9cdd5852352c0133198706125dc63b6007/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt#L6 The problem is at https://github.com/JetBrains/kotlin/blob/7e9f27436a77de1c76e3705da7aa1fbe8938336b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt#L1104 For null assignment, ideally the type should be `Nothing?`. This is addressed in a followup commit instead.
122 lines
1.7 KiB
Kotlin
Vendored
122 lines
1.7 KiB
Kotlin
Vendored
// !DUMP_CFG
|
|
class A {
|
|
val s: String = ""
|
|
}
|
|
|
|
fun test_0(list: List<A>) {
|
|
var goodA: A? = null
|
|
for (a in list) {
|
|
if (goodA == null) {
|
|
goodA = a
|
|
continue
|
|
}
|
|
goodA.s
|
|
}
|
|
}
|
|
|
|
fun test_1(a: A, b: Boolean) {
|
|
val x: Any
|
|
if (b) {
|
|
x = A()
|
|
} else {
|
|
x = a
|
|
}
|
|
x.s
|
|
}
|
|
|
|
fun test_2(a: Any, b: Boolean) {
|
|
val x: Any
|
|
if (b) {
|
|
//x1
|
|
x = A()
|
|
} else {
|
|
//x2 = a
|
|
x = a
|
|
a as A
|
|
}
|
|
x.s
|
|
}
|
|
|
|
fun test_3(a: Any, b: Boolean) {
|
|
val x: Any
|
|
if (b) {
|
|
x = A()
|
|
} else {
|
|
a as A
|
|
x = a
|
|
}
|
|
x.s
|
|
}
|
|
|
|
fun test_4(a: Any, b: Boolean) {
|
|
val x: Any
|
|
if (b) {
|
|
x = a
|
|
} else {
|
|
x = a
|
|
}
|
|
x as A
|
|
x.s
|
|
a.s
|
|
}
|
|
|
|
fun test_5(a: Any, b: Boolean) {
|
|
val x: Any
|
|
if (b) {
|
|
x = a
|
|
} else {
|
|
x = a
|
|
}
|
|
a as A
|
|
x.s
|
|
a.s
|
|
}
|
|
|
|
fun test_6(a: A) {
|
|
val x: Any
|
|
x = a
|
|
x.s
|
|
}
|
|
|
|
fun test_7() {
|
|
val z: String? = null
|
|
var y : String? = z
|
|
val x: String? = y
|
|
|
|
if (x != null) {
|
|
x.length // OK
|
|
y.length // OK
|
|
z.length // OK
|
|
}
|
|
if (y != null) {
|
|
x.length // OK
|
|
y.length // OK
|
|
z.length // OK
|
|
}
|
|
|
|
if (z != null) {
|
|
x.length // OK
|
|
y.length // OK
|
|
z.length // OK
|
|
}
|
|
|
|
y = null
|
|
|
|
if (x != null) {
|
|
x.length // OK
|
|
y<!UNSAFE_CALL!>.<!>length // Bad
|
|
z.length // OK
|
|
}
|
|
if (<!SENSELESS_COMPARISON!>y != null<!>) {
|
|
x<!UNSAFE_CALL!>.<!>length // Bad
|
|
y.length // OK
|
|
z<!UNSAFE_CALL!>.<!>length // Bad
|
|
}
|
|
|
|
if (z != null) {
|
|
x.length // OK
|
|
y<!UNSAFE_CALL!>.<!>length // Bad
|
|
z.length // OK
|
|
}
|
|
}
|