FIR CFG: route to exit of try main for throw in try main

to make the remaining part of try main marked as dead.

^KT-45475 Fixed
This commit is contained in:
Jinseong Jeon
2021-03-16 00:45:43 -07:00
committed by TeamCityServer
parent 7a7114f896
commit 922419efb8
5 changed files with 228 additions and 6 deletions
@@ -1272,10 +1272,10 @@ class ControlFlowGraphBuilder {
// (4)... in catch, i.e., re-throw.
exitTargetsForTry.top()
} else {
// (4)... in try-main. We already have:
// edges from try-main enter node to each catch clause enter node and
// edges from catch clause enter node to exit target (w/ UncaughtExceptionPath)
return
// (4)... in try-main. Route to exit of try main block.
// We already have edges from the exit of try main block to each catch clause.
// This edge makes the remaining part of try main block, e.g., following `when` branches, marked as dead.
tryMainExitNodes.top()
}
}
// (3)... within finally.
@@ -1,3 +1,4 @@
// IGNORE_FIR_DIAGNOSTICS
// FILE: 1.kt
class A(val s: String)
@@ -0,0 +1,222 @@
fun foo(): Int = 42
object ThrowInTryWithCatch {
private val p: String
init {
try {
throw Exception()
} catch (e: Exception) {
}
p = "OK"
}
}
object ThrowInTryWithCatchAndFinally {
private val p: String
init {
try {
throw Exception()
} catch (e: Exception) {
} finally {
}
p = "OK"
}
}
object ThrowInFinally {
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>private val p: String<!>
init {
try {
foo()
} catch (e: Exception) {
} finally {
throw Exception()
}
p = "OK"
}
}
object RethrowInCatch {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
throw e
}
p = "OK"
}
}
object RethrowInCatchWithFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
throw e
} finally {
}
p = "OK"
}
}
object InnerTryWithCatch {
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>private val p: String<!>
init {
try {
foo()
} catch (e: Exception) {
try {
throw e
} catch (ee: Exception) {
}
}
p = "OK"
}
}
object InnerTryWithFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
throw e
} finally {
}
}
p = "OK"
}
}
object InnerTryWithCatchAndFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
throw e
} catch (ee: Exception) {
} finally {
}
}
p = "OK"
}
}
object InnerCatch {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} catch (ee: Exception) {
throw ee
}
}
p = "OK"
}
}
object InnerCatchWithFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} catch (ee: Exception) {
throw ee
} finally {
}
}
p = "OK"
}
}
object InnerCatchOuterRethrow {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} catch (ee: Exception) {
throw e
}
}
p = "OK"
}
}
object InnerCatchOuterRethrowWithFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} catch (ee: Exception) {
throw e
} finally {
}
}
p = "OK"
}
}
object InnerFinally {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} finally {
throw e
}
}
p = "OK"
}
}
object InnerFinallyWithCatch {
private val p: String
init {
try {
foo()
} catch (e: Exception) {
try {
foo()
} catch (ee: Exception) {
} finally {
throw e
}
}
p = "OK"
}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
fun foo(): Int = 42
object ThrowInTryWithCatch {
@@ -40,7 +40,7 @@ fun conditionalThrowInTry_smartcastInTry(a: A) {
if (a !is B) {
throw AssertionError()
}
<!INAPPLICABLE_CANDIDATE!>takeB<!>(a)
takeB(a)
} catch (e: Throwable) {}
}