[FIR] Only track assignment nodes for uncaught exception edges in CFG
UncaughtExceptionPath edges are used to influence smart-casting within catch and finally blocks. Previously these edges were added from every node which could throw an exception. But only assignment nodes influence smart-casts by resetting inference back to some less specific type. Therefore, instead of tracking every possible node which could throw an exception - even though almost every statement node can - only add edges from assignment nodes to catch and finally blocks. This fixes many missing exception cases and also reduces the total number of incoming edges to catch and finally blocks. #KT-56872 Fixed
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
// !SKIP_TXT
|
||||
// DUMP_CFG
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun exc(flag: Boolean) {
|
||||
if (flag) throw RuntimeException()
|
||||
}
|
||||
|
||||
fun Any.notNull() = toString()
|
||||
|
||||
fun test(flag: Boolean) {
|
||||
var x: Any?
|
||||
x = ""
|
||||
@@ -19,3 +24,52 @@ fun test(flag: Boolean) {
|
||||
x.<!UNRESOLVED_REFERENCE!>inc<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun testGetClassThrows() {
|
||||
var x: KClass<String>? = String::class
|
||||
x as KClass<String>
|
||||
try {
|
||||
<!UNUSED_VALUE!>x =<!> null
|
||||
x = String::class
|
||||
} catch (e: Throwable) {
|
||||
// bad - get class call can throw
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.notNull()
|
||||
}
|
||||
}
|
||||
|
||||
fun testMemberReferenceThrows() {
|
||||
var x: Any? = ""
|
||||
x as Any
|
||||
try {
|
||||
<!UNUSED_VALUE!>x =<!> null
|
||||
x = String::length
|
||||
} catch (ex: Throwable) {
|
||||
// bad - get callable reference throw
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.notNull()
|
||||
}
|
||||
}
|
||||
|
||||
fun testExceptionBeforeLambda() {
|
||||
var x: String? = ""
|
||||
x as String
|
||||
try {
|
||||
x = null
|
||||
run { x = "" }
|
||||
} catch (ex: Throwable) {
|
||||
// bad - `run` could throw before running lambda
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.notNull()
|
||||
}
|
||||
}
|
||||
|
||||
fun testExceptionWithinLocalFunction() {
|
||||
var x: Any = ""
|
||||
x as String
|
||||
try {
|
||||
fun local() {
|
||||
x = 1
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// bad - `local` could be run and reset smartcasting
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user