FIR: report UNSAFE_CALL on dot when possible

This commit is contained in:
Mikhail Glukhikh
2021-01-29 10:25:59 +03:00
parent 0ee4f1f393
commit 7d4eaefd36
249 changed files with 1208 additions and 1649 deletions
@@ -1,11 +1,11 @@
// !WITH_NEW_INFERENCE
fun foo() {
var v: String? = null
v.<!UNSAFE_CALL!>length<!>
v<!UNSAFE_CALL!>.<!>length
v = "abc"
v.length
v = null
v.<!UNSAFE_CALL!>length<!>
v<!UNSAFE_CALL!>.<!>length
v = "abc"
v.length
}
@@ -23,7 +23,7 @@ fun bar(s: String?) {
val hashCode = ss?.hashCode()
ss = null
if (hashCode != null) {
ss.<!UNSAFE_CALL!>hashCode<!>()
ss<!UNSAFE_CALL!>.<!>hashCode()
}
}
@@ -41,6 +41,6 @@ fun baz(arg: Some?) {
val ss = arg?.s
if (ss != null) {
arg.hashCode()
arg.s.<!UNSAFE_CALL!>hashCode<!>()
arg.s<!UNSAFE_CALL!>.<!>hashCode()
}
}
@@ -37,7 +37,7 @@ fun test3() {
catch (e: B) {
return
}
a.<!UNSAFE_CALL!>hashCode<!>() // a is nullable here
a<!UNSAFE_CALL!>.<!>hashCode() // a is nullable here
}
fun test4() {
var a: Int? = null
@@ -50,7 +50,7 @@ fun test4() {
catch (e: B) {
return
}
a.<!UNSAFE_CALL!>hashCode<!>() // a is nullable here
a<!UNSAFE_CALL!>.<!>hashCode() // a is nullable here
}
fun test5() {
var a: Int?// = null
@@ -76,5 +76,5 @@ fun test6() {
finally {
a = null
}
a.<!UNSAFE_CALL!>hashCode<!>() // a is null here
a<!UNSAFE_CALL!>.<!>hashCode() // a is null here
}
@@ -2,7 +2,7 @@
fun foo() {
var v: String? = "xyz"
// It is possible in principle to provide smart cast here
v.<!UNSAFE_CALL!>length<!>
v<!UNSAFE_CALL!>.<!>length
v = null
v.<!UNSAFE_CALL!>length<!>
v<!UNSAFE_CALL!>.<!>length
}
@@ -12,7 +12,7 @@ fun foo(): Bar {
var y: Bar? = Bar()
while (x != null) {
// Here call is unsafe because of initialization and also inner loop
y.<!UNSAFE_CALL!>next<!>()
y<!UNSAFE_CALL!>.<!>next()
while (y != null) {
if (x == y)
// x is not null because of outer while
@@ -1,8 +0,0 @@
operator fun Int?.inc(): Int? { return this }
public fun box(arg: Int?) : Int? {
var i : Int? = arg
var j = i++
j.<!UNSAFE_CALL!>toInt<!>()
return i
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
operator fun Int?.inc(): Int? { return this }
public fun box(arg: Int?) : Int? {
@@ -1,13 +0,0 @@
class MyClass
// Correct at compile time but wrong at run-time
operator fun MyClass?.inc(): MyClass? { return null }
public fun box() {
var i : MyClass?
i = MyClass()
// type of j should be MyClass?
var j = ++i
// j is null so call should be unsafe
j.<!UNSAFE_CALL!>hashCode<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class MyClass
// Correct at compile time but wrong at run-time
@@ -1,8 +0,0 @@
operator fun Int?.inc(): Int? { return this }
public fun box(arg: Int?) : Int? {
var i = arg
var j = ++i
j.<!UNSAFE_CALL!>toInt<!>()
return ++j
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
operator fun Int?.inc(): Int? { return this }
public fun box(arg: Int?) : Int? {
@@ -1,14 +0,0 @@
// !LANGUAGE: +SoundSmartCastsAfterTry
fun bar(arg: Any?) = arg
fun foo() {
var s: String?
s = null
try {
s = "Test"
} catch (ex: Exception) {}
bar(s)
if (s != null) { }
s.<!UNSAFE_CALL!>hashCode<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SoundSmartCastsAfterTry
fun bar(arg: Any?) = arg
@@ -1,10 +0,0 @@
// !LANGUAGE: +SoundSmartCastsAfterTry
fun foo() {
var s: String?
s = "Test"
try {
s = null
} catch (ex: Exception) {}
s.<!UNSAFE_CALL!>hashCode<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SoundSmartCastsAfterTry
fun foo() {
@@ -1,16 +0,0 @@
// !LANGUAGE: +SoundSmartCastsAfterTry
fun bar() {}
fun foo() {
var s: String?
s = "Test"
try {
s = null
}
catch (ex: Exception) {}
finally {
bar()
}
s.<!UNSAFE_CALL!>hashCode<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SoundSmartCastsAfterTry
fun bar() {}
@@ -6,5 +6,5 @@ fun foo() {
try {
s = null
} catch (ex: Exception) {}
s.<!UNSAFE_CALL!>hashCode<!>()
s<!UNSAFE_CALL!>.<!>hashCode()
}
@@ -2,5 +2,5 @@
fun foo(): Int {
var s: String? = "abc"
s = null
return s.<!UNSAFE_CALL!>length<!>
return s<!UNSAFE_CALL!>.<!>length
}