== sample == fun sample(): String? { try { if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } } } finally {} return null } --------------------- L0: 1 INIT: in: {} out: {} 2 mark({ try { if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } } } finally {} return null }) mark(try { if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } } } finally {}) jmp?(L2) 3 mark({ if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } } }) mark(if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } }) r(false) -> jf(L3|) 4 mark({ return "fail" }) jmp?(L2) mark("fail") r("fail") -> L4 [start finally]: 5 mark({}) read (Unit) L5 [finish finally]: 4 ret(*|) L1 USE: in: {} out: {} - 3 jmp(L6) L3 [else branch]: 4 mark({ if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } }) INIT: in: {} out: {} mark(if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" }) r(false) -> jf(L7|) 5 mark({ if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" }) mark(if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } }) r(false) -> jf(L8|) USE: in: {} out: {} 6 mark({ var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } }) v(var foo: String? = null) INIT: in: {} out: {foo=D} r(null) -> INIT: in: {foo=D} out: {foo=D} w(foo|) INIT: in: {foo=D} out: {foo=ID} mark(try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized }) INIT: in: {foo=ID} out: {foo=ID} jmp?(L9) jmp?(L10) USE: in: {foo=READ} out: {foo=READ} 7 mark({ foo = "test" }) mark("test") r("test") -> USE: in: {foo=WRITTEN_AFTER_READ} out: {foo=WRITTEN_AFTER_READ} w(foo|) USE: in: {foo=READ} out: {foo=WRITTEN_AFTER_READ} 6 jmp?(L9) jmp?(L10) jmp(L11) L9 [onException]: 7 v(e: Exception) INIT: in: {foo=ID} out: {foo=ID} magic[FAKE_INITIALIZER](e: Exception) -> INIT: in: {foo=ID} out: {foo=ID} w(e|) INIT: in: {foo=ID} out: {foo=ID} 8 mark({ return "fail" }) INIT: in: {foo=ID} out: {foo=ID} jmp?(L2) mark("fail") r("fail") -> L12 [start finally]: 9 mark({ println(foo) // Variable 'foo' must be initialized }) USE: in: {foo=READ} out: {foo=READ} r(foo) -> USE: in: {} out: {foo=READ} mark(println(foo)) magic[UNRESOLVED_CALL](println(foo)|, !) -> L13 [finish finally]: 5 mark({}) INIT: in: {} out: {} read (Unit) 8 ret(*|) L1 USE: in: {} out: {} - 7 jmp(L11) L11 [afterCatches]: 6 jmp(L14) INIT: in: {foo=ID} out: {foo=ID} L10 [onExceptionToFinallyBlock]: 9 mark({ println(foo) // Variable 'foo' must be initialized }) USE: in: {foo=READ} out: {foo=READ} r(foo) -> USE: in: {} out: {foo=READ} mark(println(foo)) magic[UNRESOLVED_CALL](println(foo)|, !) -> 5 mark({}) INIT: in: {} out: {} read (Unit) 6 jmp(error) USE: in: {} out: {} L14 [skipFinallyToErrorBlock]: 9 mark({ println(foo) // Variable 'foo' must be initialized }) INIT: in: {foo=ID} out: {foo=ID} USE: in: {foo=READ} out: {foo=READ} r(foo) -> USE: in: {} out: {foo=READ} mark(println(foo)) magic[UNRESOLVED_CALL](println(foo)|, !) -> 6 merge(try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized }|!, !) -> 5 jmp(L15) INIT: in: {} out: {} L8 [else branch]: read (Unit) L15 ['if' expression result]: merge(if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } }|) -> jmp?(L2) mark("fail") r("fail") -> mark({}) read (Unit) ret(*|) L1 USE: in: {} out: {} - 4 jmp(L16) L7 [else branch]: read (Unit) INIT: in: {} out: {} L16 ['if' expression result]: merge(if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" }|!) -> L6 ['if' expression result]: 3 merge(if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } }|!, ) -> 2 jmp?(L2) jmp(L17) L2 [onExceptionToFinallyBlock]: 5 mark({}) read (Unit) 2 jmp(error) L17 [skipFinallyToErrorBlock]: 5 mark({}) read (Unit) 2 merge(try { if (false) { return "fail" } else { if (false) { if (false) { var foo: String? = null try { foo = "test" } catch (e: Exception) { return "fail" } finally { println(foo) // Variable 'foo' must be initialized } } return "fail" } } } finally {}|) -> r(null) -> ret(*|) L1 L1: 1 error: sink: USE: in: {} out: {} =====================