Pseudocode and CFG changed after 'let' is resolved correctly.
This commit is contained in:
+23
-23
@@ -98,22 +98,22 @@ L0:
|
|||||||
d(fun f(x: Any?) = x) NEXT:[<SINK>]
|
d(fun f(x: Any?) = x) NEXT:[<SINK>]
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
mark(null?.let { return }) PREV:[jmp?(L2)]
|
mark(null?.let { return }) PREV:[jmp?(L2)]
|
||||||
jf(L5) NEXT:[mark(f(null?.let { return })), mark({ return })]
|
jf(L5) NEXT:[mark(f(null?.let { return })), r(null) -> <v0>]
|
||||||
|
r(null) -> <v0>
|
||||||
mark({ return })
|
mark({ return })
|
||||||
jmp?(L6) NEXT:[r({ return }) -> <v0>, d({ return })]
|
jmp?(L6) NEXT:[r({ return }) -> <v1>, d({ return })]
|
||||||
d({ return }) NEXT:[<SINK>]
|
d({ return }) NEXT:[<SINK>]
|
||||||
L6 [after local declaration]:
|
L6 [after local declaration]:
|
||||||
r({ return }) -> <v0> PREV:[jmp?(L6)]
|
r({ return }) -> <v1> PREV:[jmp?(L6)]
|
||||||
r(null) -> <v1>
|
|
||||||
mark(let { return })
|
mark(let { return })
|
||||||
magic[UNRESOLVED_CALL](let { return }|<v0>, !<v2>, <v1>) -> <v3>
|
call(let { return }, let|<v0>, <v1>)
|
||||||
L5 [result of call]:
|
L5 [result of call]:
|
||||||
mark(f(null?.let { return })) PREV:[jf(L5), magic[UNRESOLVED_CALL](let { return }|<v0>, !<v2>, <v1>) -> <v3>]
|
mark(f(null?.let { return })) PREV:[jf(L5), call(let { return }, let|<v0>, <v1>)]
|
||||||
call(f(null?.let { return }), f|<v3>) -> <v4>
|
call(f(null?.let { return }), f|!<v2>) -> <v3>
|
||||||
mark(doSomething())
|
mark(doSomething())
|
||||||
call(doSomething(), doSomething) -> <v5>
|
call(doSomething(), doSomething) -> <v4>
|
||||||
L1:
|
L1:
|
||||||
1 <END> NEXT:[<SINK>] PREV:[ret L1, call(doSomething(), doSomething) -> <v5>]
|
1 <END> NEXT:[<SINK>] PREV:[ret L1, call(doSomething(), doSomething) -> <v4>]
|
||||||
error:
|
error:
|
||||||
<ERROR> PREV:[]
|
<ERROR> PREV:[]
|
||||||
sink:
|
sink:
|
||||||
@@ -163,28 +163,28 @@ L0:
|
|||||||
magic[FAKE_INITIALIZER](x: Any?) -> <v0>
|
magic[FAKE_INITIALIZER](x: Any?) -> <v0>
|
||||||
w(x|<v0>)
|
w(x|<v0>)
|
||||||
mark(x?.let { return true })
|
mark(x?.let { return true })
|
||||||
jf(L2) NEXT:[mark(x?.let { return true } ?: false), mark({ return true })]
|
jf(L2) NEXT:[mark(x?.let { return true } ?: false), r(x) -> <v1>]
|
||||||
|
r(x) -> <v1>
|
||||||
mark({ return true })
|
mark({ return true })
|
||||||
jmp?(L3) NEXT:[r({ return true }) -> <v1>, d({ return true })]
|
jmp?(L3) NEXT:[r({ return true }) -> <v2>, d({ return true })]
|
||||||
d({ return true }) NEXT:[<SINK>]
|
d({ return true }) NEXT:[<SINK>]
|
||||||
L3 [after local declaration]:
|
L3 [after local declaration]:
|
||||||
r({ return true }) -> <v1> PREV:[jmp?(L3)]
|
r({ return true }) -> <v2> PREV:[jmp?(L3)]
|
||||||
r(x) -> <v2>
|
|
||||||
mark(let { return true })
|
mark(let { return true })
|
||||||
magic[UNRESOLVED_CALL](let { return true }|<v1>, !<v3>, <v2>) -> <v4>
|
call(let { return true }, let|<v1>, <v2>)
|
||||||
L2 [result of call]:
|
L2 [result of call]:
|
||||||
mark(x?.let { return true } ?: false) PREV:[jf(L2), magic[UNRESOLVED_CALL](let { return true }|<v1>, !<v3>, <v2>) -> <v4>]
|
mark(x?.let { return true } ?: false) PREV:[jf(L2), call(let { return true }, let|<v1>, <v2>)]
|
||||||
jt(L6|<v4>) NEXT:[r(false) -> <v5>, merge(x?.let { return true } ?: false|<v4>, <v5>) -> <v6>]
|
jt(L6|!<v3>) NEXT:[r(false) -> <v4>, merge(x?.let { return true } ?: false|!<v3>, <v4>) -> <v5>]
|
||||||
r(false) -> <v5>
|
r(false) -> <v4>
|
||||||
L6 [after elvis operator]:
|
L6 [after elvis operator]:
|
||||||
merge(x?.let { return true } ?: false|<v4>, <v5>) -> <v6> PREV:[jt(L6|<v4>), r(false) -> <v5>]
|
merge(x?.let { return true } ?: false|!<v3>, <v4>) -> <v5> PREV:[jt(L6|!<v3>), r(false) -> <v4>]
|
||||||
ret(*|<v6>) L1
|
ret(*|<v5>) L1
|
||||||
L1:
|
L1:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v6>) L1]
|
<END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v5>) L1]
|
||||||
error:
|
error:
|
||||||
<ERROR> PREV:[]
|
<ERROR> PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> PREV:[<ERROR>, <END>, d({ return true })]
|
<SINK> PREV:[<ERROR>, <END>, d({ return true })]
|
||||||
=====================
|
=====================
|
||||||
== anonymous_2 ==
|
== anonymous_2 ==
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-16
@@ -43,14 +43,13 @@ fun test2() {
|
|||||||
doSomething()
|
doSomething()
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
null <v1>: * NEW: r(null) -> <v1>
|
null <v0>: Nothing NEW: r(null) -> <v0>
|
||||||
let !<v2>: *
|
{ return } <v1>: {<: (Nothing) -> Nothing} NEW: r({ return }) -> <v1>
|
||||||
{ return } <v0>: * NEW: r({ return }) -> <v0>
|
let { return } !<v2>: *
|
||||||
let { return } <v3>: * NEW: magic[UNRESOLVED_CALL](let { return }|<v0>, !<v2>, <v1>) -> <v3>
|
null?.let { return } !<v2>: * COPY
|
||||||
null?.let { return } <v3>: * COPY
|
f(null?.let { return }) <v3>: * NEW: call(f(null?.let { return }), f|!<v2>) -> <v3>
|
||||||
f(null?.let { return }) <v4>: * NEW: call(f(null?.let { return }), f|<v3>) -> <v4>
|
doSomething() <v4>: * NEW: call(doSomething(), doSomething) -> <v4>
|
||||||
doSomething() <v5>: * NEW: call(doSomething(), doSomething) -> <v5>
|
{ fun f(x: Any?) = x f(null?.let { return }) // false unreachable here doSomething() } <v4>: * COPY
|
||||||
{ fun f(x: Any?) = x f(null?.let { return }) // false unreachable here doSomething() } <v5>: * COPY
|
|
||||||
=====================
|
=====================
|
||||||
== f ==
|
== f ==
|
||||||
fun f(x: Any?) = x
|
fun f(x: Any?) = x
|
||||||
@@ -70,14 +69,13 @@ fun test3(x: Any?): Boolean =
|
|||||||
return true
|
return true
|
||||||
} ?: false
|
} ?: false
|
||||||
---------------------
|
---------------------
|
||||||
<v0>: * NEW: magic[FAKE_INITIALIZER](x: Any?) -> <v0>
|
<v0>: * NEW: magic[FAKE_INITIALIZER](x: Any?) -> <v0>
|
||||||
x <v2>: * NEW: r(x) -> <v2>
|
x <v1>: {<: Any} NEW: r(x) -> <v1>
|
||||||
let !<v3>: *
|
{ return true } <v2>: {<: (Any) -> Nothing} NEW: r({ return true }) -> <v2>
|
||||||
{ return true } <v1>: * NEW: r({ return true }) -> <v1>
|
let { return true } !<v3>: *
|
||||||
let { return true } <v4>: Boolean NEW: magic[UNRESOLVED_CALL](let { return true }|<v1>, !<v3>, <v2>) -> <v4>
|
x?.let { return true } !<v3>: * COPY
|
||||||
x?.let { return true } <v4>: Boolean COPY
|
false <v4>: Boolean NEW: r(false) -> <v4>
|
||||||
false <v5>: Boolean NEW: r(false) -> <v5>
|
x?.let { return true } ?: false <v5>: Boolean NEW: merge(x?.let { return true } ?: false|!<v3>, <v4>) -> <v5>
|
||||||
x?.let { return true } ?: false <v6>: Boolean NEW: merge(x?.let { return true } ?: false|<v4>, <v5>) -> <v6>
|
|
||||||
=====================
|
=====================
|
||||||
== anonymous_2 ==
|
== anonymous_2 ==
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user