== doSmth == fun doSmth() {} --------------------- L0: 1 2 mark({}) read (Unit) L1: 1 NEXT:[] error: PREV:[] sink: PREV:[, ] ===================== == doSmth1 == fun doSmth1() {} --------------------- L0: 1 2 mark({}) read (Unit) L1: 1 NEXT:[] error: PREV:[] sink: PREV:[, ] ===================== == doSmth2 == fun doSmth2() {} --------------------- L0: 1 2 mark({}) read (Unit) L1: 1 NEXT:[] error: PREV:[] sink: PREV:[, ] ===================== == cond == fun cond() {} --------------------- L0: 1 2 mark({}) read (Unit) L1: 1 NEXT:[] error: PREV:[] sink: PREV:[, ] ===================== == testCopy1 == fun testCopy1() : Int { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } } --------------------- L0: 1 2 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } }) mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }) jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)] jmp?(L3) NEXT:[mark({ return 1 }), mark({ doSmth() })] 3 mark({ doSmth() }) mark(doSmth()) call(doSmth(), doSmth) -> 2 jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)] jmp?(L3) NEXT:[mark({ return 1 }), jmp(L4)] jmp(L4) NEXT:[jmp(L6)] L2 [onException]: jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2), jmp?(L2)] 3 v(e: NullPointerException) magic[FAKE_INITIALIZER](e: NullPointerException) -> w(e|) 4 mark({ doSmth1() }) mark(doSmth1()) call(doSmth1(), doSmth1) -> 3 jmp(L4) NEXT:[jmp(L6)] L5 [catch 0]: v(e: Exception) PREV:[jmp?(L5)] magic[FAKE_INITIALIZER](e: Exception) -> w(e|) 4 mark({ doSmth2() }) mark(doSmth2()) call(doSmth2(), doSmth2) -> 3 jmp(L4) L4 [afterCatches]: 2 jmp(L6) NEXT:[mark({ return 1 })] PREV:[jmp(L4), jmp(L4), jmp(L4)] L3 [onExceptionToFinallyBlock]: L7 [start finally]: 3 mark({ return 1 }) PREV:[jmp?(L3), jmp?(L3)] r(1) -> ret(*|) L1 NEXT:[] L8 [finish finally]: - 2 jmp(error) NEXT:[] PREV:[] L6 [skipFinallyToErrorBlock]: L9 [copy of L3, onExceptionToFinallyBlock]: 3 mark({ return 1 }) PREV:[jmp(L6)] r(1) -> ret(*|) L1 NEXT:[] - 2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|, , ) -> PREV:[] L1: 1 NEXT:[] PREV:[ret(*|) L1, ret(*|) L1] error: PREV:[] sink: PREV:[, ] ===================== == testCopy2 == fun testCopy2() { while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } } --------------------- L0: 1 2 mark({ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } }) L2 [loop entry point]: L6 [condition entry point]: mark(cond()) PREV:[mark({ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } }), jmp(L6), jmp(L6)] call(cond(), cond) -> mark(while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } }) jf(L3|) NEXT:[read (Unit), mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })] L4 [body entry point]: 3 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } }) mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }) jmp?(L7) NEXT:[jmp?(L10), jmp?(L8)] jmp?(L8) NEXT:[mark({ if (cond()) return else continue }), mark({ doSmth() })] 4 mark({ doSmth() }) mark(doSmth()) call(doSmth(), doSmth) -> 3 jmp?(L7) NEXT:[jmp?(L10), jmp?(L8)] jmp?(L8) NEXT:[mark({ if (cond()) return else continue }), jmp(L9)] jmp(L9) NEXT:[jmp(L11)] L7 [onException]: jmp?(L10) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L7), jmp?(L7)] 4 v(e: NullPointerException) magic[FAKE_INITIALIZER](e: NullPointerException) -> w(e|) 5 mark({ doSmth1() }) mark(doSmth1()) call(doSmth1(), doSmth1) -> 4 jmp(L9) NEXT:[jmp(L11)] L10 [catch 0]: v(e: Exception) PREV:[jmp?(L10)] magic[FAKE_INITIALIZER](e: Exception) -> w(e|) 5 mark({ doSmth2() }) mark(doSmth2()) call(doSmth2(), doSmth2) -> 4 jmp(L9) L9 [afterCatches]: 3 jmp(L11) NEXT:[mark({ if (cond()) return else continue })] PREV:[jmp(L9), jmp(L9), jmp(L9)] L8 [onExceptionToFinallyBlock]: L12 [start finally]: 4 mark({ if (cond()) return else continue }) PREV:[jmp?(L8), jmp?(L8)] mark(if (cond()) return else continue) mark(cond()) call(cond(), cond) -> jf(L13|) NEXT:[jmp(L6), ret L1] ret L1 NEXT:[] - jmp(L14) NEXT:[merge(if (cond()) return else continue|!, !) -> ] PREV:[] L13 [else branch]: jmp(L6) NEXT:[mark(cond())] PREV:[jf(L13|)] L14 ['if' expression result]: - merge(if (cond()) return else continue|!, !) -> PREV:[] L15 [finish finally]: - 3 jmp(error) NEXT:[] PREV:[] L11 [skipFinallyToErrorBlock]: L16 [copy of L8, onExceptionToFinallyBlock]: 4 mark({ if (cond()) return else continue }) PREV:[jmp(L11)] mark(if (cond()) return else continue) mark(cond()) call(cond(), cond) -> jf(L17|) NEXT:[jmp(L6), ret L1] ret L1 NEXT:[] - jmp(L18) NEXT:[merge(if (cond()) return else continue|!, !) -> ] PREV:[] L17 [copy of L13, else branch]: jmp(L6) NEXT:[mark(cond())] PREV:[jf(L17|)] L18 [copy of L14, 'if' expression result]: - merge(if (cond()) return else continue|!, !) -> PREV:[] - 3 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|, , ) -> PREV:[] - 2 jmp(L2) NEXT:[mark(cond())] PREV:[] L3 [loop exit point]: L5 [body exit point]: read (Unit) PREV:[jf(L3|)] L1: 1 NEXT:[] PREV:[ret L1, ret L1, read (Unit)] error: PREV:[] sink: PREV:[, ] ===================== == testCopy3 == fun testCopy3() { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } } --------------------- L0: 1 2 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } }) mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }) jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)] jmp?(L3) NEXT:[mark({ while (cond()); }), mark({ doSmth() })] 3 mark({ doSmth() }) mark(doSmth()) call(doSmth(), doSmth) -> 2 jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)] jmp?(L3) NEXT:[mark({ while (cond()); }), jmp(L4)] jmp(L4) NEXT:[jmp(L6)] L2 [onException]: jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2), jmp?(L2)] 3 v(e: NullPointerException) magic[FAKE_INITIALIZER](e: NullPointerException) -> w(e|) 4 mark({ doSmth1() }) mark(doSmth1()) call(doSmth1(), doSmth1) -> 3 jmp(L4) NEXT:[jmp(L6)] L5 [catch 0]: v(e: Exception) PREV:[jmp?(L5)] magic[FAKE_INITIALIZER](e: Exception) -> w(e|) 4 mark({ doSmth2() }) mark(doSmth2()) call(doSmth2(), doSmth2) -> 3 jmp(L4) L4 [afterCatches]: 2 jmp(L6) NEXT:[mark({ while (cond()); })] PREV:[jmp(L4), jmp(L4), jmp(L4)] L3 [onExceptionToFinallyBlock]: L7 [start finally]: 3 mark({ while (cond()); }) PREV:[jmp?(L3), jmp?(L3)] L8 [loop entry point]: L12 [condition entry point]: mark(cond()) PREV:[mark({ while (cond()); }), jmp(L8)] call(cond(), cond) -> mark(while (cond())) jf(L9|) NEXT:[read (Unit), jmp(L8)] L10 [body entry point]: jmp(L8) NEXT:[mark(cond())] L9 [loop exit point]: L11 [body exit point]: read (Unit) PREV:[jf(L9|)] L13 [finish finally]: 2 jmp(error) NEXT:[] L6 [skipFinallyToErrorBlock]: L14 [copy of L3, onExceptionToFinallyBlock]: 3 mark({ while (cond()); }) PREV:[jmp(L6)] L15 [copy of L8, loop entry point]: L19 [copy of L12, condition entry point]: mark(cond()) PREV:[mark({ while (cond()); }), jmp(L15)] call(cond(), cond) -> mark(while (cond())) jf(L16|) NEXT:[read (Unit), jmp(L15)] L17 [copy of L10, body entry point]: jmp(L15) NEXT:[mark(cond())] L16 [copy of L9, loop exit point]: L18 [copy of L11, body exit point]: read (Unit) PREV:[jf(L16|)] 2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|, , ) -> L1: 1 NEXT:[] error: PREV:[jmp(error)] sink: PREV:[, ] ===================== == doTestCopy4 == fun doTestCopy4(list: List?) : Int { try { doSmth() } finally { if(list != null) { } } } --------------------- L0: 1 v(list: List?) magic[FAKE_INITIALIZER](list: List?) -> w(list|) 2 mark({ try { doSmth() } finally { if(list != null) { } } }) mark(try { doSmth() } finally { if(list != null) { } }) jmp?(L2) NEXT:[mark({ if(list != null) { } }), mark({ doSmth() })] 3 mark({ doSmth() }) mark(doSmth()) call(doSmth(), doSmth) -> 2 jmp?(L2) NEXT:[mark({ if(list != null) { } }), jmp(L3)] jmp(L3) NEXT:[mark({ if(list != null) { } })] L2 [onExceptionToFinallyBlock]: L4 [start finally]: 3 mark({ if(list != null) { } }) PREV:[jmp?(L2), jmp?(L2)] mark(if(list != null) { }) r(list) -> r(null) -> mark(list != null) call(list != null, equals|, ) -> jf(L5|) NEXT:[read (Unit), mark({ })] 4 mark({ }) read (Unit) 3 jmp(L6) NEXT:[merge(if(list != null) { }|!) -> ] L5 [else branch]: read (Unit) PREV:[jf(L5|)] L6 ['if' expression result]: merge(if(list != null) { }|!) -> PREV:[jmp(L6), read (Unit)] L7 [finish finally]: 2 jmp(error) NEXT:[] L3 [skipFinallyToErrorBlock]: L8 [copy of L2, onExceptionToFinallyBlock]: 3 mark({ if(list != null) { } }) PREV:[jmp(L3)] mark(if(list != null) { }) r(list) -> r(null) -> mark(list != null) call(list != null, equals|, ) -> jf(L9|) NEXT:[read (Unit), mark({ })] 4 mark({ }) read (Unit) 3 jmp(L10) NEXT:[merge(if(list != null) { }|!) -> ] L9 [copy of L5, else branch]: read (Unit) PREV:[jf(L9|)] L10 [copy of L6, 'if' expression result]: merge(if(list != null) { }|!) -> PREV:[jmp(L10), read (Unit)] 2 merge(try { doSmth() } finally { if(list != null) { } }|) -> L1: 1 NEXT:[] error: PREV:[jmp(error)] sink: PREV:[, ] =====================