Initialization analysis : more accurate handling of non-local variables while merging data #KT-14304 Fixed
This commit is contained in:
@@ -94,7 +94,7 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
) {
|
) {
|
||||||
instruction: Instruction, incomingEdgesData: Collection<InitControlFlowInfo> ->
|
instruction: Instruction, incomingEdgesData: Collection<InitControlFlowInfo> ->
|
||||||
|
|
||||||
val enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData)
|
val enterInstructionData = mergeIncomingEdgesDataForInitializers(instruction, incomingEdgesData, blockScopeVariableInfo)
|
||||||
val exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
val exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
||||||
instruction, enterInstructionData, blockScopeVariableInfo)
|
instruction, enterInstructionData, blockScopeVariableInfo)
|
||||||
Edges(enterInstructionData, exitInstructionData)
|
Edges(enterInstructionData, exitInstructionData)
|
||||||
@@ -207,7 +207,9 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeIncomingEdgesDataForInitializers(
|
private fun mergeIncomingEdgesDataForInitializers(
|
||||||
incomingEdgesData: Collection<InitControlFlowInfo>
|
instruction: Instruction,
|
||||||
|
incomingEdgesData: Collection<InitControlFlowInfo>,
|
||||||
|
blockScopeVariableInfo: BlockScopeVariableInfo
|
||||||
): InitControlFlowInfo {
|
): InitControlFlowInfo {
|
||||||
if (incomingEdgesData.size == 1) return incomingEdgesData.single()
|
if (incomingEdgesData.size == 1) return incomingEdgesData.single()
|
||||||
val variablesInScope = linkedSetOf<VariableDescriptor>()
|
val variablesInScope = linkedSetOf<VariableDescriptor>()
|
||||||
@@ -220,7 +222,8 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
var initState: InitState? = null
|
var initState: InitState? = null
|
||||||
var isDeclared = true
|
var isDeclared = true
|
||||||
for (edgeData in incomingEdgesData) {
|
for (edgeData in incomingEdgesData) {
|
||||||
val varControlFlowState = edgeData[variable] ?: VariableControlFlowState.create(isInitialized = false)
|
val varControlFlowState = edgeData[variable]
|
||||||
|
?: getDefaultValueForInitializers(variable, instruction, blockScopeVariableInfo)
|
||||||
initState = initState?.merge(varControlFlowState.initState) ?: varControlFlowState.initState
|
initState = initState?.merge(varControlFlowState.initState) ?: varControlFlowState.initState
|
||||||
if (!varControlFlowState.isDeclared) {
|
if (!varControlFlowState.isDeclared) {
|
||||||
isDeclared = false
|
isDeclared = false
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ L0:
|
|||||||
v(val f = { x: Int -> val y = x + a use(a) }) INIT: in: {a=ID} out: {a=ID, f=D}
|
v(val f = { x: Int -> val y = x + a use(a) }) INIT: in: {a=ID} out: {a=ID, f=D}
|
||||||
mark({ x: Int -> val y = x + a use(a) }) INIT: in: {a=ID, f=D} out: {a=ID, f=D}
|
mark({ x: Int -> val y = x + a use(a) }) INIT: in: {a=ID, f=D} out: {a=ID, f=D}
|
||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
d({ x: Int -> val y = x + a use(a) }) INIT: in: {a=I?, f=-} out: {a=I?, f=-} USE: in: {a=READ} out: {a=READ}
|
d({ x: Int -> val y = x + a use(a) }) INIT: in: {a=I, f=I?} out: {a=I, f=I?} USE: in: {a=READ} out: {a=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r({ x: Int -> val y = x + a use(a) }) -> <v1> INIT: in: {a=ID, f=D} out: {a=ID, f=D}
|
r({ x: Int -> val y = x + a use(a) }) -> <v1> INIT: in: {a=ID, f=D} out: {a=ID, f=D}
|
||||||
w(f|<v1>) INIT: in: {a=ID, f=D} out: {a=ID, f=ID}
|
w(f|<v1>) INIT: in: {a=ID, f=D} out: {a=ID, f=ID}
|
||||||
@@ -54,7 +54,7 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {a=I?, f=-, x=I?} out: {a=I?, f=-, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {a=I, f=I?, x=I?} out: {a=I, f=I?, x=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== use ==
|
== use ==
|
||||||
fun use(vararg a: Any?) = a
|
fun use(vararg a: Any?) = a
|
||||||
|
|||||||
+6
-6
@@ -24,12 +24,12 @@ fun foo() {
|
|||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
L0:
|
L0:
|
||||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||||
2 mark({ var v: Any bar { v.hashCode() } })
|
2 mark({ var v: Any bar { v.hashCode() } })
|
||||||
v(var v: Any) INIT: in: {} out: {v=D}
|
v(var v: Any) INIT: in: {} out: {v=D}
|
||||||
mark({ v.hashCode() }) INIT: in: {v=D} out: {v=D}
|
mark({ v.hashCode() }) INIT: in: {v=D} out: {v=D}
|
||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
d({ v.hashCode() }) INIT: in: {v=-} out: {v=-} USE: in: {v=READ} out: {v=READ}
|
d({ v.hashCode() }) INIT: in: {v=I?} out: {v=I?} USE: in: {v=READ} out: {v=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r({ v.hashCode() }) -> <v0> INIT: in: {v=D} out: {v=D}
|
r({ v.hashCode() }) -> <v0> INIT: in: {v=D} out: {v=D}
|
||||||
mark(bar { v.hashCode() })
|
mark(bar { v.hashCode() })
|
||||||
@@ -39,7 +39,7 @@ L1:
|
|||||||
error:
|
error:
|
||||||
<ERROR>
|
<ERROR>
|
||||||
sink:
|
sink:
|
||||||
<SINK> USE: in: {} out: {}
|
<SINK> USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== anonymous_0 ==
|
== anonymous_0 ==
|
||||||
{ v.hashCode() }
|
{ v.hashCode() }
|
||||||
@@ -47,8 +47,8 @@ sink:
|
|||||||
L3:
|
L3:
|
||||||
3 <START> INIT: in: {v=D} out: {v=D}
|
3 <START> INIT: in: {v=D} out: {v=D}
|
||||||
4 mark(v.hashCode())
|
4 mark(v.hashCode())
|
||||||
mark(v.hashCode()) USE: in: {v=READ} out: {v=READ}
|
mark(v.hashCode()) USE: in: {v=READ} out: {v=READ}
|
||||||
r(v) -> <v0> USE: in: {} out: {v=READ}
|
r(v) -> <v0> USE: in: {} out: {v=READ}
|
||||||
mark(hashCode())
|
mark(hashCode())
|
||||||
call(hashCode(), hashCode|<v0>) -> <v1>
|
call(hashCode(), hashCode|<v0>) -> <v1>
|
||||||
L4:
|
L4:
|
||||||
@@ -56,5 +56,5 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {v=-} out: {v=-} USE: in: {} out: {}
|
<SINK> INIT: in: {v=I?} out: {v=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
+14
-14
@@ -32,46 +32,46 @@ L0:
|
|||||||
mark(try { if (f) { x = 0 } } finally { fun bar() {} })
|
mark(try { if (f) { x = 0 } } finally { fun bar() {} })
|
||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
3 mark({ if (f) { x = 0 } })
|
3 mark({ if (f) { x = 0 } })
|
||||||
mark(if (f) { x = 0 }) USE: in: {f=READ, x=ONLY_WRITTEN_NEVER_READ} out: {f=READ, x=ONLY_WRITTEN_NEVER_READ}
|
mark(if (f) { x = 0 }) USE: in: {f=READ, x=ONLY_WRITTEN_NEVER_READ} out: {f=READ, x=ONLY_WRITTEN_NEVER_READ}
|
||||||
r(f) -> <v1> USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {f=READ, x=ONLY_WRITTEN_NEVER_READ}
|
r(f) -> <v1> USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {f=READ, x=ONLY_WRITTEN_NEVER_READ}
|
||||||
jf(L3|<v1>)
|
jf(L3|<v1>)
|
||||||
4 mark({ x = 0 })
|
4 mark({ x = 0 })
|
||||||
r(0) -> <v2> USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {x=ONLY_WRITTEN_NEVER_READ}
|
r(0) -> <v2> USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||||
w(x|<v2>) INIT: in: {f=ID} out: {f=ID, x=I} USE: in: {} out: {x=ONLY_WRITTEN_NEVER_READ}
|
w(x|<v2>) INIT: in: {f=ID} out: {f=ID, x=I} USE: in: {} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||||
3 jmp(L4) INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
3 jmp(L4) INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
L3 [else branch]:
|
L3 [else branch]:
|
||||||
read (Unit) INIT: in: {f=ID} out: {f=ID}
|
read (Unit) INIT: in: {f=ID} out: {f=ID}
|
||||||
L4 ['if' expression result]:
|
L4 ['if' expression result]:
|
||||||
merge(if (f) { x = 0 }|!<v3>) -> <v4> INIT: in: {f=ID, x=I?} out: {f=ID, x=I?}
|
merge(if (f) { x = 0 }|!<v3>) -> <v4> INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
2 jmp?(L2)
|
2 jmp?(L2)
|
||||||
jmp(L5)
|
jmp(L5)
|
||||||
L2 [onExceptionToFinallyBlock]:
|
L2 [onExceptionToFinallyBlock]:
|
||||||
L6 [start finally]:
|
L6 [start finally]:
|
||||||
3 mark({ fun bar() {} })
|
3 mark({ fun bar() {} })
|
||||||
jmp?(L7)
|
jmp?(L7)
|
||||||
d(fun bar() {}) INIT: in: {f=I?, x=I?} out: {f=I?, x=I?}
|
d(fun bar() {}) INIT: in: {f=I, x=I} out: {f=I, x=I}
|
||||||
L7 [after local declaration]:
|
L7 [after local declaration]:
|
||||||
L10 [finish finally]:
|
L10 [finish finally]:
|
||||||
2 jmp(error) INIT: in: {f=ID, x=I?} out: {f=ID, x=I?}
|
2 jmp(error) INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
L5 [skipFinallyToErrorBlock]:
|
L5 [skipFinallyToErrorBlock]:
|
||||||
L11 [copy of L2, onExceptionToFinallyBlock]:
|
L11 [copy of L2, onExceptionToFinallyBlock]:
|
||||||
3 mark({ fun bar() {} })
|
3 mark({ fun bar() {} })
|
||||||
jmp?(L12)
|
jmp?(L12)
|
||||||
d(fun bar() {}) INIT: in: {f=I?, x=I?} out: {f=I?, x=I?}
|
d(fun bar() {}) INIT: in: {f=I, x=I} out: {f=I, x=I}
|
||||||
L12 [copy of L7, after local declaration]:
|
L12 [copy of L7, after local declaration]:
|
||||||
2 merge(try { if (f) { x = 0 } } finally { fun bar() {} }|<v4>) -> <v5> INIT: in: {f=ID, x=I?} out: {f=ID, x=I?}
|
2 merge(try { if (f) { x = 0 } } finally { fun bar() {} }|<v4>) -> <v5> INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
L1:
|
L1:
|
||||||
1 <END>
|
1 <END>
|
||||||
error:
|
error:
|
||||||
<ERROR>
|
<ERROR>
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {f=I?, x=I?} out: {f=I?, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {f=I, x=I} out: {f=I, x=I} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== bar ==
|
== bar ==
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
---------------------
|
---------------------
|
||||||
L8:
|
L8:
|
||||||
4 <START> INIT: in: {f=ID, x=I?} out: {f=ID, x=I?}
|
4 <START> INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
5 mark({})
|
5 mark({})
|
||||||
read (Unit)
|
read (Unit)
|
||||||
L9:
|
L9:
|
||||||
@@ -79,13 +79,13 @@ L9:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {f=I?, x=I?} out: {f=I?, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {f=I, x=I} out: {f=I, x=I} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== bar ==
|
== bar ==
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
---------------------
|
---------------------
|
||||||
L2 [copy of L8, null]:
|
L2 [copy of L8, null]:
|
||||||
4 <START> INIT: in: {f=ID, x=I?} out: {f=ID, x=I?}
|
4 <START> INIT: in: {f=ID, x=I} out: {f=ID, x=I}
|
||||||
5 mark({})
|
5 mark({})
|
||||||
read (Unit)
|
read (Unit)
|
||||||
L3 [copy of L9, null]:
|
L3 [copy of L9, null]:
|
||||||
@@ -93,5 +93,5 @@ L3 [copy of L9, null]:
|
|||||||
L0 [copy of error, null]:
|
L0 [copy of error, null]:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
L1 [copy of sink, null]:
|
L1 [copy of sink, null]:
|
||||||
<SINK> INIT: in: {f=I?, x=I?} out: {f=I?, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {f=I, x=I} out: {f=I, x=I} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -0,0 +1,485 @@
|
|||||||
|
== println ==
|
||||||
|
fun println(obj: Any?) {}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(obj: Any?) INIT: in: {} out: {obj=D}
|
||||||
|
magic[FAKE_INITIALIZER](obj: Any?) -> <v0> INIT: in: {obj=D} out: {obj=D}
|
||||||
|
w(obj|<v0>) INIT: in: {obj=D} out: {obj=ID}
|
||||||
|
2 mark({}) INIT: in: {obj=ID} out: {obj=ID}
|
||||||
|
read (Unit)
|
||||||
|
L1:
|
||||||
|
1 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {obj=I?} out: {obj=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo0 ==
|
||||||
|
class Demo0 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private val some = object { fun foo() { println(state) // Ok } }) INIT: in: {} out: {some=D}
|
||||||
|
mark(object { fun foo() { println(state) // Ok } }) INIT: in: {some=D} out: {some=D}
|
||||||
|
jmp?(L2)
|
||||||
|
d(fun foo() { println(state) // Ok }) INIT: in: {some=I?} out: {some=I?} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r(object { fun foo() { println(state) // Ok } }) -> <v0> INIT: in: {some=D} out: {some=D}
|
||||||
|
w(some|<v0>) INIT: in: {some=D} out: {some=ID}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {some=ID} out: {some=ID, state=D}
|
||||||
|
r(true) -> <v1> INIT: in: {some=ID, state=D} out: {some=ID, state=D}
|
||||||
|
w(state|<v1>) INIT: in: {some=ID, state=D} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
|
3 mark({ println(state) // Ok })
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v0>) -> <v1> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v1>) -> <v2>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo1 ==
|
||||||
|
class Demo1 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private val some = object { fun foo() { if (state) state = true println(state) // must be initialized } }) INIT: in: {} out: {some=D}
|
||||||
|
mark(object { fun foo() { if (state) state = true println(state) // must be initialized } }) INIT: in: {some=D} out: {some=D}
|
||||||
|
jmp?(L2)
|
||||||
|
d(fun foo() { if (state) state = true println(state) // must be initialized }) INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r(object { fun foo() { if (state) state = true println(state) // must be initialized } }) -> <v0> INIT: in: {some=D} out: {some=D}
|
||||||
|
w(some|<v0>) INIT: in: {some=D} out: {some=ID}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {some=ID} out: {some=ID, state=D}
|
||||||
|
r(true) -> <v1> INIT: in: {some=ID, state=D} out: {some=ID, state=D}
|
||||||
|
w(state|<v1>) INIT: in: {some=ID, state=D} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
|
3 mark({ if (state) state = true println(state) // must be initialized })
|
||||||
|
mark(if (state) state = true)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
r(state|<v0>) -> <v1>
|
||||||
|
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
|
L5 [else branch]:
|
||||||
|
read (Unit) INIT: in: {some=D} out: {some=D}
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v7>) -> <v8>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo1A ==
|
||||||
|
class Demo1A {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {} out: {state=D}
|
||||||
|
r(true) -> <v0> INIT: in: {state=D} out: {state=D}
|
||||||
|
w(state|<v0>) INIT: in: {state=D} out: {state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {state=ID} out: {state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {state=I?} out: {state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
2 mark({ if (state) state = true println(state) // Ok })
|
||||||
|
mark(if (state) state = true)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
r(state|<v0>) -> <v1>
|
||||||
|
jf(L2|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) INIT: in: {} out: {state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L3) INIT: in: {state=I} out: {state=I}
|
||||||
|
L2 [else branch]:
|
||||||
|
read (Unit) INIT: in: {} out: {}
|
||||||
|
L3 ['if' expression result]:
|
||||||
|
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {state=I} out: {state=I}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v7>) -> <v8>
|
||||||
|
L1:
|
||||||
|
1 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {state=I} out: {state=I} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo2 ==
|
||||||
|
class Demo2 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private val some = object { fun foo() { if (state) state = true else state = false println(state) // OK } }) INIT: in: {} out: {some=D}
|
||||||
|
mark(object { fun foo() { if (state) state = true else state = false println(state) // OK } }) INIT: in: {some=D} out: {some=D}
|
||||||
|
jmp?(L2)
|
||||||
|
d(fun foo() { if (state) state = true else state = false println(state) // OK }) INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r(object { fun foo() { if (state) state = true else state = false println(state) // OK } }) -> <v0> INIT: in: {some=D} out: {some=D}
|
||||||
|
w(some|<v0>) INIT: in: {some=D} out: {some=ID}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {some=ID} out: {some=ID, state=D}
|
||||||
|
r(true) -> <v1> INIT: in: {some=ID, state=D} out: {some=ID, state=D}
|
||||||
|
w(state|<v1>) INIT: in: {some=ID, state=D} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
|
3 mark({ if (state) state = true else state = false println(state) // OK })
|
||||||
|
mark(if (state) state = true else state = false)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v0>) -> <v1> USE: in: {state=WRITTEN_AFTER_READ} out: {state=READ}
|
||||||
|
jf(L5|<v1>)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L5 [else branch]:
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v4> INIT: in: {some=D} out: {some=D}
|
||||||
|
r(false) -> <v5> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v4>, <v5>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (state) state = true else state = false|!<v6>, !<v7>) -> <v8> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v9> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v9>) -> <v10> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v10>) -> <v11>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo3 ==
|
||||||
|
class Demo3 {
|
||||||
|
private val some = run {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private val some = run { if (state) state = true println(state) // OK }) INIT: in: {} out: {some=D}
|
||||||
|
magic[IMPLICIT_RECEIVER](run { if (state) state = true println(state) // OK }) -> <v0> INIT: in: {some=D} out: {some=D}
|
||||||
|
mark({ if (state) state = true println(state) // OK })
|
||||||
|
jmp?(L2)
|
||||||
|
d({ if (state) state = true println(state) // OK }) INIT: in: {some=I?} out: {some=I?} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r({ if (state) state = true println(state) // OK }) -> <v1> INIT: in: {some=D} out: {some=D}
|
||||||
|
mark(run { if (state) state = true println(state) // OK })
|
||||||
|
call(run { if (state) state = true println(state) // OK }, run|<v0>, <v1>) -> <v2>
|
||||||
|
w(some|<v2>) INIT: in: {some=D} out: {some=ID}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {some=ID} out: {some=ID, state=D}
|
||||||
|
r(true) -> <v3> INIT: in: {some=ID, state=D} out: {some=ID, state=D}
|
||||||
|
w(state|<v3>) INIT: in: {some=ID, state=D} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== anonymous_0 ==
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
|
3 mark(if (state) state = true println(state))
|
||||||
|
mark(if (state) state = true)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
r(state|<v0>) -> <v1>
|
||||||
|
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L6)
|
||||||
|
L5 [else branch]:
|
||||||
|
read (Unit)
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v7>) -> <v8>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?} out: {some=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== exec ==
|
||||||
|
fun <T> exec(f: () -> T): T = f()
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(f: () -> T) INIT: in: {} out: {f=D}
|
||||||
|
magic[FAKE_INITIALIZER](f: () -> T) -> <v0> INIT: in: {f=D} out: {f=D}
|
||||||
|
w(f|<v0>) INIT: in: {f=D} out: {f=ID} USE: in: {f=READ} out: {f=READ}
|
||||||
|
r(f) -> <v1> INIT: in: {f=ID} out: {f=ID} USE: in: {} out: {f=READ}
|
||||||
|
mark(f())
|
||||||
|
call(f(), invoke|<v1>) -> <v2>
|
||||||
|
ret(*|<v2>) L1
|
||||||
|
L1:
|
||||||
|
<END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {f=I?} out: {f=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo4 ==
|
||||||
|
class Demo4 {
|
||||||
|
private val some = exec {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private val some = exec { if (state) state = true println(state) // must be initialized }) INIT: in: {} out: {some=D}
|
||||||
|
mark({ if (state) state = true println(state) // must be initialized }) INIT: in: {some=D} out: {some=D}
|
||||||
|
jmp?(L2)
|
||||||
|
d({ if (state) state = true println(state) // must be initialized }) INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r({ if (state) state = true println(state) // must be initialized }) -> <v0> INIT: in: {some=D} out: {some=D}
|
||||||
|
mark(exec { if (state) state = true println(state) // must be initialized })
|
||||||
|
call(exec { if (state) state = true println(state) // must be initialized }, exec|<v0>) -> <v1>
|
||||||
|
w(some|<v1>) INIT: in: {some=D} out: {some=ID}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {some=ID} out: {some=ID, state=D}
|
||||||
|
r(true) -> <v2> INIT: in: {some=ID, state=D} out: {some=ID, state=D}
|
||||||
|
w(state|<v2>) INIT: in: {some=ID, state=D} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== anonymous_1 ==
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D} out: {some=D}
|
||||||
|
3 mark(if (state) state = true println(state))
|
||||||
|
mark(if (state) state = true)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
r(state|<v0>) -> <v1>
|
||||||
|
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) INIT: in: {some=D} out: {some=D, state=I} USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L6) INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
|
L5 [else branch]:
|
||||||
|
read (Unit) INIT: in: {some=D} out: {some=D}
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (state) state = true|!<v4>) -> <v5> INIT: in: {some=D, state=I} out: {some=D, state=I}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v7>) -> <v8>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== Demo5 ==
|
||||||
|
class Demo5 {
|
||||||
|
private var state: Boolean = true
|
||||||
|
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(private var state: Boolean = true) INIT: in: {} out: {state=D}
|
||||||
|
r(true) -> <v0> INIT: in: {state=D} out: {state=D}
|
||||||
|
w(state|<v0>) INIT: in: {state=D} out: {state=ID}
|
||||||
|
v(private val some = object { fun foo() { if (state) state = true println(state) // OK } }) INIT: in: {state=ID} out: {some=D, state=ID}
|
||||||
|
mark(object { fun foo() { if (state) state = true println(state) // OK } }) INIT: in: {some=D, state=ID} out: {some=D, state=ID}
|
||||||
|
jmp?(L2)
|
||||||
|
d(fun foo() { if (state) state = true println(state) // OK }) INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {state=READ} out: {state=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r(object { fun foo() { if (state) state = true println(state) // OK } }) -> <v1> INIT: in: {some=D, state=ID} out: {some=D, state=ID}
|
||||||
|
w(some|<v1>) INIT: in: {some=D, state=ID} out: {some=ID, state=ID}
|
||||||
|
L1:
|
||||||
|
<END> INIT: in: {some=ID, state=ID} out: {some=ID, state=ID}
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I?} out: {some=I?, state=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {some=D, state=ID} out: {some=D, state=ID}
|
||||||
|
3 mark({ if (state) state = true println(state) // OK })
|
||||||
|
mark(if (state) state = true)
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
r(state|<v0>) -> <v1>
|
||||||
|
jf(L5|<v1>) USE: in: {state=READ} out: {state=READ}
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
r(true) -> <v3> USE: in: {state=WRITTEN_AFTER_READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
w(state|<v2>, <v3>) USE: in: {state=READ} out: {state=WRITTEN_AFTER_READ}
|
||||||
|
jmp(L6)
|
||||||
|
L5 [else branch]:
|
||||||
|
read (Unit)
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
magic[IMPLICIT_RECEIVER](state) -> <v6> USE: in: {state=READ} out: {state=READ}
|
||||||
|
r(state|<v6>) -> <v7> USE: in: {} out: {state=READ}
|
||||||
|
mark(println(state))
|
||||||
|
call(println(state), println|<v7>) -> <v8>
|
||||||
|
L4:
|
||||||
|
2 <END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {some=I?, state=I} out: {some=I?, state=I} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
fun println(obj: Any?) {}
|
||||||
|
|
||||||
|
class Demo0 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo1 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo1A {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo2 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo3 {
|
||||||
|
private val some = run {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> exec(f: () -> T): T = f()
|
||||||
|
|
||||||
|
class Demo4 {
|
||||||
|
private val some = exec {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo5 {
|
||||||
|
private var state: Boolean = true
|
||||||
|
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
== println ==
|
||||||
|
fun println(obj: Any?) {}
|
||||||
|
---------------------
|
||||||
|
<v0>: * NEW: magic[FAKE_INITIALIZER](obj: Any?) -> <v0>
|
||||||
|
=====================
|
||||||
|
== Demo0 ==
|
||||||
|
class Demo0 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
object { fun foo() { println(state) // Ok } } <v0>: <no name provided> NEW: r(object { fun foo() { println(state) // Ok } }) -> <v0>
|
||||||
|
true <v1>: Boolean NEW: r(true) -> <v1>
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo0 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
state <v1>: * NEW: r(state|<v0>) -> <v1>
|
||||||
|
println(state) <v2>: * NEW: call(println(state), println|<v1>) -> <v2>
|
||||||
|
{ println(state) // Ok } <v2>: * COPY
|
||||||
|
=====================
|
||||||
|
== Demo1 ==
|
||||||
|
class Demo1 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
object { fun foo() { if (state) state = true println(state) // must be initialized } } <v0>: <no name provided> NEW: r(object { fun foo() { if (state) state = true println(state) // must be initialized } }) -> <v0>
|
||||||
|
true <v1>: Boolean NEW: r(true) -> <v1>
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo1 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo1 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v6>: Demo1 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v4>: *
|
||||||
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
|
{ if (state) state = true println(state) // must be initialized } <v8>: * COPY
|
||||||
|
=====================
|
||||||
|
== Demo1A ==
|
||||||
|
class Demo1A {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
true <v0>: Boolean NEW: r(true) -> <v0>
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // Ok
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo1A NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo1A NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v6>: Demo1A NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v4>: *
|
||||||
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
|
{ if (state) state = true println(state) // Ok } <v8>: * COPY
|
||||||
|
=====================
|
||||||
|
== Demo2 ==
|
||||||
|
class Demo2 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
object { fun foo() { if (state) state = true else state = false println(state) // OK } } <v0>: <no name provided> NEW: r(object { fun foo() { if (state) state = true else state = false println(state) // OK } }) -> <v0>
|
||||||
|
true <v1>: Boolean NEW: r(true) -> <v1>
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo2 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo2 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v4>: Demo2 NEW: magic[IMPLICIT_RECEIVER](state) -> <v4>
|
||||||
|
<v9>: Demo2 NEW: magic[IMPLICIT_RECEIVER](state) -> <v9>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v6>: *
|
||||||
|
false <v5>: Boolean NEW: r(false) -> <v5>
|
||||||
|
state = false !<v7>: *
|
||||||
|
if (state) state = true else state = false <v8>: * NEW: merge(if (state) state = true else state = false|!<v6>, !<v7>) -> <v8>
|
||||||
|
state <v10>: * NEW: r(state|<v9>) -> <v10>
|
||||||
|
println(state) <v11>: * NEW: call(println(state), println|<v10>) -> <v11>
|
||||||
|
{ if (state) state = true else state = false println(state) // OK } <v11>: * COPY
|
||||||
|
=====================
|
||||||
|
== Demo3 ==
|
||||||
|
class Demo3 {
|
||||||
|
private val some = run {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](run { if (state) state = true println(state) // OK }) -> <v0>
|
||||||
|
{ if (state) state = true println(state) // OK } <v1>: {<: Demo3.() -> Unit} NEW: r({ if (state) state = true println(state) // OK }) -> <v1>
|
||||||
|
run { if (state) state = true println(state) // OK } <v2>: Unit NEW: call(run { if (state) state = true println(state) // OK }, run|<v0>, <v1>) -> <v2>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
=====================
|
||||||
|
== anonymous_0 ==
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v6>: Demo3 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v4>: *
|
||||||
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
|
if (state) state = true println(state) <v8>: * COPY
|
||||||
|
=====================
|
||||||
|
== exec ==
|
||||||
|
fun <T> exec(f: () -> T): T = f()
|
||||||
|
---------------------
|
||||||
|
<v0>: {<: () -> T} NEW: magic[FAKE_INITIALIZER](f: () -> T) -> <v0>
|
||||||
|
f <v1>: {<: () -> T} NEW: r(f) -> <v1>
|
||||||
|
f() <v2>: {<: T} NEW: call(f(), invoke|<v1>) -> <v2>
|
||||||
|
=====================
|
||||||
|
== Demo4 ==
|
||||||
|
class Demo4 {
|
||||||
|
private val some = exec {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
{ if (state) state = true println(state) // must be initialized } <v0>: {<: () -> Unit} NEW: r({ if (state) state = true println(state) // must be initialized }) -> <v0>
|
||||||
|
exec { if (state) state = true println(state) // must be initialized } <v1>: Unit NEW: call(exec { if (state) state = true println(state) // must be initialized }, exec|<v0>) -> <v1>
|
||||||
|
true <v2>: Boolean NEW: r(true) -> <v2>
|
||||||
|
=====================
|
||||||
|
== anonymous_1 ==
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // must be initialized
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v6>: Demo4 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v4>: *
|
||||||
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
|
if (state) state = true println(state) <v8>: * COPY
|
||||||
|
=====================
|
||||||
|
== Demo5 ==
|
||||||
|
class Demo5 {
|
||||||
|
private var state: Boolean = true
|
||||||
|
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
true <v0>: Boolean NEW: r(true) -> <v0>
|
||||||
|
object { fun foo() { if (state) state = true println(state) // OK } } <v1>: <no name provided> NEW: r(object { fun foo() { if (state) state = true println(state) // OK } }) -> <v1>
|
||||||
|
=====================
|
||||||
|
== foo ==
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state) // OK
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
<v0>: Demo5 NEW: magic[IMPLICIT_RECEIVER](state) -> <v0>
|
||||||
|
<v2>: Demo5 NEW: magic[IMPLICIT_RECEIVER](state) -> <v2>
|
||||||
|
<v6>: Demo5 NEW: magic[IMPLICIT_RECEIVER](state) -> <v6>
|
||||||
|
state <v1>: Boolean NEW: r(state|<v0>) -> <v1>
|
||||||
|
true <v3>: Boolean NEW: r(true) -> <v3>
|
||||||
|
state = true !<v4>: *
|
||||||
|
if (state) state = true <v5>: * NEW: merge(if (state) state = true|!<v4>) -> <v5>
|
||||||
|
state <v7>: * NEW: r(state|<v6>) -> <v7>
|
||||||
|
println(state) <v8>: * NEW: call(println(state), println|<v7>) -> <v8>
|
||||||
|
{ if (state) state = true println(state) // OK } <v8>: * COPY
|
||||||
|
=====================
|
||||||
+8
-8
@@ -10,7 +10,7 @@ L0:
|
|||||||
v(val sum: (Int)->Int = { x: Int -> sum(x - 1) + x }) INIT: in: {} out: {sum=D}
|
v(val sum: (Int)->Int = { x: Int -> sum(x - 1) + x }) INIT: in: {} out: {sum=D}
|
||||||
mark({ x: Int -> sum(x - 1) + x }) INIT: in: {sum=D} out: {sum=D}
|
mark({ x: Int -> sum(x - 1) + x }) INIT: in: {sum=D} out: {sum=D}
|
||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
d({ x: Int -> sum(x - 1) + x }) INIT: in: {sum=-} out: {sum=-} USE: in: {sum=READ} out: {sum=READ}
|
d({ x: Int -> sum(x - 1) + x }) INIT: in: {sum=I?} out: {sum=I?} USE: in: {sum=READ} out: {sum=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r({ x: Int -> sum(x - 1) + x }) -> <v0> INIT: in: {sum=D} out: {sum=D}
|
r({ x: Int -> sum(x - 1) + x }) -> <v0> INIT: in: {sum=D} out: {sum=D}
|
||||||
w(sum|<v0>) INIT: in: {sum=D} out: {sum=ID}
|
w(sum|<v0>) INIT: in: {sum=D} out: {sum=ID}
|
||||||
@@ -32,15 +32,15 @@ L3:
|
|||||||
magic[FAKE_INITIALIZER](x: Int) -> <v0> INIT: in: {sum=D, x=D} out: {sum=D, x=D}
|
magic[FAKE_INITIALIZER](x: Int) -> <v0> INIT: in: {sum=D, x=D} out: {sum=D, x=D}
|
||||||
w(x|<v0>) INIT: in: {sum=D, x=D} out: {sum=D, x=ID}
|
w(x|<v0>) INIT: in: {sum=D, x=D} out: {sum=D, x=ID}
|
||||||
3 mark(sum(x - 1) + x) INIT: in: {sum=D, x=ID} out: {sum=D, x=ID}
|
3 mark(sum(x - 1) + x) INIT: in: {sum=D, x=ID} out: {sum=D, x=ID}
|
||||||
magic[IMPLICIT_RECEIVER](sum) -> <v1> USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ}
|
magic[IMPLICIT_RECEIVER](sum) -> <v1> USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ}
|
||||||
r(sum|<v1>) -> <v2> USE: in: {x=READ} out: {sum=READ, x=READ}
|
r(sum|<v1>) -> <v2> USE: in: {x=READ} out: {sum=READ, x=READ}
|
||||||
r(x) -> <v3>
|
r(x) -> <v3>
|
||||||
r(1) -> <v4>
|
r(1) -> <v4>
|
||||||
mark(x - 1)
|
mark(x - 1)
|
||||||
call(x - 1, minus|<v3>, <v4>) -> <v5>
|
call(x - 1, minus|<v3>, <v4>) -> <v5>
|
||||||
mark(sum(x - 1))
|
mark(sum(x - 1))
|
||||||
call(sum(x - 1), invoke|<v2>, <v5>) -> <v6> USE: in: {x=READ} out: {x=READ}
|
call(sum(x - 1), invoke|<v2>, <v5>) -> <v6> USE: in: {x=READ} out: {x=READ}
|
||||||
r(x) -> <v7> USE: in: {} out: {x=READ}
|
r(x) -> <v7> USE: in: {} out: {x=READ}
|
||||||
mark(sum(x - 1) + x)
|
mark(sum(x - 1) + x)
|
||||||
call(sum(x - 1) + x, plus|<v6>, <v7>) -> <v8>
|
call(sum(x - 1) + x, plus|<v6>, <v7>) -> <v8>
|
||||||
2 ret(*|<v8>) L4
|
2 ret(*|<v8>) L4
|
||||||
@@ -49,7 +49,7 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {sum=-, x=I?} out: {sum=-, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {sum=I?, x=I?} out: {sum=I?, x=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== A ==
|
== A ==
|
||||||
open class A(val a: A)
|
open class A(val a: A)
|
||||||
@@ -92,7 +92,7 @@ L0:
|
|||||||
r(obj|<v3>) -> <v4>
|
r(obj|<v3>) -> <v4>
|
||||||
w(x|<v4>) INIT: in: {obj=D, x=D} out: {obj=D, x=ID}
|
w(x|<v4>) INIT: in: {obj=D, x=D} out: {obj=D, x=ID}
|
||||||
1 jmp?(L2) INIT: in: {obj=D} out: {obj=D}
|
1 jmp?(L2) INIT: in: {obj=D} out: {obj=D}
|
||||||
d(fun foo() { val y = obj }) INIT: in: {obj=-} out: {obj=-} USE: in: {obj=READ} out: {obj=READ}
|
d(fun foo() { val y = obj }) INIT: in: {obj=I?} out: {obj=I?} USE: in: {obj=READ} out: {obj=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r(object: A(obj) { init { val x = obj } fun foo() { val y = obj } }) -> <v5> INIT: in: {obj=D} out: {obj=D}
|
r(object: A(obj) { init { val x = obj } fun foo() { val y = obj } }) -> <v5> INIT: in: {obj=D} out: {obj=D}
|
||||||
w(obj|<v5>) INIT: in: {obj=D} out: {obj=ID}
|
w(obj|<v5>) INIT: in: {obj=D} out: {obj=ID}
|
||||||
@@ -120,7 +120,7 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {obj=-} out: {obj=-} USE: in: {} out: {}
|
<SINK> INIT: in: {obj=I?} out: {obj=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== TestOther ==
|
== TestOther ==
|
||||||
class TestOther {
|
class TestOther {
|
||||||
|
|||||||
+2
-2
@@ -19,7 +19,7 @@ L0:
|
|||||||
v(val f = { x: Int -> val a = x + b }) INIT: in: {b=ID} out: {b=ID, f=D}
|
v(val f = { x: Int -> val a = x + b }) INIT: in: {b=ID} out: {b=ID, f=D}
|
||||||
mark({ x: Int -> val a = x + b }) INIT: in: {b=ID, f=D} out: {b=ID, f=D}
|
mark({ x: Int -> val a = x + b }) INIT: in: {b=ID, f=D} out: {b=ID, f=D}
|
||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
d({ x: Int -> val a = x + b }) INIT: in: {b=I?, f=-} out: {b=I?, f=-} USE: in: {b=READ} out: {b=READ}
|
d({ x: Int -> val a = x + b }) INIT: in: {b=I, f=I?} out: {b=I, f=I?} USE: in: {b=READ} out: {b=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r({ x: Int -> val a = x + b }) -> <v2> INIT: in: {b=ID, f=D} out: {b=ID, f=D}
|
r({ x: Int -> val a = x + b }) -> <v2> INIT: in: {b=ID, f=D} out: {b=ID, f=D}
|
||||||
w(f|<v2>) INIT: in: {b=ID, f=D} out: {b=ID, f=ID}
|
w(f|<v2>) INIT: in: {b=ID, f=D} out: {b=ID, f=ID}
|
||||||
@@ -54,5 +54,5 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {b=I?, f=-, x=I?} out: {b=I?, f=-, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {b=I, f=I?, x=I?} out: {b=I, f=I?, x=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ L0:
|
|||||||
r(x|<v2>) -> <v3>
|
r(x|<v2>) -> <v3>
|
||||||
w(a|<v3>) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
w(a|<v3>) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||||
2 jmp?(L3) INIT: in: {x=ID} out: {x=ID}
|
2 jmp?(L3) INIT: in: {x=ID} out: {x=ID}
|
||||||
d(fun foo() { val b = x }) INIT: in: {x=I?} out: {x=I?} USE: in: {x=READ} out: {x=READ}
|
d(fun foo() { val b = x }) INIT: in: {x=I} out: {x=I} USE: in: {x=READ} out: {x=READ}
|
||||||
L2 [after local class]:
|
L2 [after local class]:
|
||||||
L3 [after local declaration]:
|
L3 [after local declaration]:
|
||||||
mark("after")
|
mark("after") INIT: in: {x=I?} out: {x=I?}
|
||||||
r("after") -> <v4>
|
r("after") -> <v4>
|
||||||
L1:
|
L1:
|
||||||
1 <END> INIT: in: {} out: {}
|
1 <END> INIT: in: {} out: {}
|
||||||
@@ -56,5 +56,5 @@ L5:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {x=I?} out: {x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {x=I} out: {x=I} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ L0:
|
|||||||
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
||||||
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
||||||
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
||||||
d(fun local(x: Int) { val a = x + b }) INIT: in: {b=I?} out: {b=I?} USE: in: {b=READ} out: {b=READ}
|
d(fun local(x: Int) { val a = x + b }) INIT: in: {b=I} out: {b=I} USE: in: {b=READ} out: {b=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
mark("after") INIT: in: {b=ID} out: {b=ID}
|
mark("after") INIT: in: {b=ID} out: {b=ID}
|
||||||
r("after") -> <v2>
|
r("after") -> <v2>
|
||||||
@@ -50,5 +50,5 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {b=I?, x=I?} out: {b=I?, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {b=I, x=I?} out: {b=I, x=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
+2
-2
@@ -15,7 +15,7 @@ L0:
|
|||||||
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
||||||
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
||||||
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
||||||
d(fun local(x: Int) = x + b) INIT: in: {b=I?} out: {b=I?} USE: in: {b=READ} out: {b=READ}
|
d(fun local(x: Int) = x + b) INIT: in: {b=I} out: {b=I} USE: in: {b=READ} out: {b=READ}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
mark("after") INIT: in: {b=ID} out: {b=ID}
|
mark("after") INIT: in: {b=ID} out: {b=ID}
|
||||||
r("after") -> <v2>
|
r("after") -> <v2>
|
||||||
@@ -44,5 +44,5 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {b=I?, x=I?} out: {b=I?, x=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {b=I, x=I?} out: {b=I, x=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
+2
-2
@@ -24,7 +24,7 @@ L0:
|
|||||||
r(1) -> <v1> INIT: in: {bar=D, x=D} out: {bar=D, x=D}
|
r(1) -> <v1> INIT: in: {bar=D, x=D} out: {bar=D, x=D}
|
||||||
w(x|<v1>) INIT: in: {bar=D, x=D} out: {bar=D, x=ID}
|
w(x|<v1>) INIT: in: {bar=D, x=D} out: {bar=D, x=ID}
|
||||||
2 jmp?(L2) INIT: in: {bar=D} out: {bar=D}
|
2 jmp?(L2) INIT: in: {bar=D} out: {bar=D}
|
||||||
d(fun foo() { val a = 2 }) INIT: in: {bar=-} out: {bar=-}
|
d(fun foo() { val a = 2 }) INIT: in: {bar=I?} out: {bar=I?}
|
||||||
L2 [after local declaration]:
|
L2 [after local declaration]:
|
||||||
r(object { init { val x = 1 } fun foo() { val a = 2 } }) -> <v2> INIT: in: {bar=D} out: {bar=D}
|
r(object { init { val x = 1 } fun foo() { val a = 2 } }) -> <v2> INIT: in: {bar=D} out: {bar=D}
|
||||||
w(bar|<v2>) INIT: in: {bar=D} out: {bar=ID}
|
w(bar|<v2>) INIT: in: {bar=D} out: {bar=ID}
|
||||||
@@ -53,5 +53,5 @@ L4:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {bar=-} out: {bar=-} USE: in: {} out: {}
|
<SINK> INIT: in: {bar=I?} out: {bar=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
+7
-7
@@ -17,10 +17,10 @@ L0:
|
|||||||
jmp?(L2)
|
jmp?(L2)
|
||||||
v(var a : Int get() { return field } set(v: Int) { field = v }) INIT: in: {} out: {a=D}
|
v(var a : Int get() { return field } set(v: Int) { field = v }) INIT: in: {} out: {a=D}
|
||||||
jmp?(L3) INIT: in: {a=D} out: {a=D} USE: in: {field=ONLY_WRITTEN_NEVER_READ, field=READ} out: {field=ONLY_WRITTEN_NEVER_READ, field=READ}
|
jmp?(L3) INIT: in: {a=D} out: {a=D} USE: in: {field=ONLY_WRITTEN_NEVER_READ, field=READ} out: {field=ONLY_WRITTEN_NEVER_READ, field=READ}
|
||||||
d(get() { return field }) INIT: in: {a=-} out: {a=-} USE: in: {field=READ} out: {field=READ}
|
d(get() { return field }) INIT: in: {a=I?} out: {a=I?} USE: in: {field=READ} out: {field=READ}
|
||||||
L3 [after local declaration]:
|
L3 [after local declaration]:
|
||||||
jmp?(L6) INIT: in: {a=D} out: {a=D}
|
jmp?(L6) INIT: in: {a=D} out: {a=D}
|
||||||
d(set(v: Int) { field = v }) INIT: in: {a=-, field=I?} out: {a=-, field=I?} USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ}
|
d(set(v: Int) { field = v }) INIT: in: {a=I?, field=I} out: {a=I?, field=I} USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ}
|
||||||
L1:
|
L1:
|
||||||
L2 [after local class]:
|
L2 [after local class]:
|
||||||
L6 [after local declaration]:
|
L6 [after local declaration]:
|
||||||
@@ -28,7 +28,7 @@ L6 [after local declaration]:
|
|||||||
error:
|
error:
|
||||||
<ERROR>
|
<ERROR>
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {field=I?} out: {field=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {field=I} out: {field=I} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== get_a ==
|
== get_a ==
|
||||||
get() {
|
get() {
|
||||||
@@ -37,15 +37,15 @@ get() {
|
|||||||
---------------------
|
---------------------
|
||||||
L4:
|
L4:
|
||||||
3 <START> INIT: in: {a=D} out: {a=D}
|
3 <START> INIT: in: {a=D} out: {a=D}
|
||||||
4 mark({ return field }) USE: in: {field=READ} out: {field=READ}
|
4 mark({ return field }) USE: in: {field=READ} out: {field=READ}
|
||||||
r(field) -> <v0> USE: in: {} out: {field=READ}
|
r(field) -> <v0> USE: in: {} out: {field=READ}
|
||||||
ret(*|<v0>) L5
|
ret(*|<v0>) L5
|
||||||
L5:
|
L5:
|
||||||
3 <END>
|
3 <END>
|
||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {a=-} out: {a=-} USE: in: {} out: {}
|
<SINK> INIT: in: {a=I?} out: {a=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
== set_a ==
|
== set_a ==
|
||||||
set(v: Int) {
|
set(v: Int) {
|
||||||
@@ -65,5 +65,5 @@ L8:
|
|||||||
error:
|
error:
|
||||||
<ERROR> INIT: in: {} out: {}
|
<ERROR> INIT: in: {} out: {}
|
||||||
sink:
|
sink:
|
||||||
<SINK> INIT: in: {a=-, field=I?, v=I?} out: {a=-, field=I?, v=I?} USE: in: {} out: {}
|
<SINK> INIT: in: {a=I?, field=I, v=I?} out: {a=I?, field=I, v=I?} USE: in: {} out: {}
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
fun println(obj: Any?) = obj
|
||||||
|
|
||||||
|
class Demo0 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo1 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo1A {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo2 {
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
else
|
||||||
|
state = false
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo3 {
|
||||||
|
private val some = run {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> exec(f: () -> T): T = f()
|
||||||
|
|
||||||
|
class Demo4 {
|
||||||
|
private val some = exec {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
class Demo5 {
|
||||||
|
private var state: Boolean = true
|
||||||
|
|
||||||
|
private val some = object {
|
||||||
|
fun foo() {
|
||||||
|
if (state)
|
||||||
|
state = true
|
||||||
|
|
||||||
|
println(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> exec(/*0*/ f: () -> T): T
|
||||||
|
public fun println(/*0*/ obj: kotlin.Any?): kotlin.Any?
|
||||||
|
|
||||||
|
public final class Demo0 {
|
||||||
|
public constructor Demo0()
|
||||||
|
private final val some: Demo0.some.<no name provided>
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo1 {
|
||||||
|
public constructor Demo1()
|
||||||
|
private final val some: Demo1.some.<no name provided>
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo1A {
|
||||||
|
public constructor Demo1A()
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo2 {
|
||||||
|
public constructor Demo2()
|
||||||
|
private final val some: Demo2.some.<no name provided>
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo3 {
|
||||||
|
public constructor Demo3()
|
||||||
|
private final val some: kotlin.Any?
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo4 {
|
||||||
|
public constructor Demo4()
|
||||||
|
private final val some: kotlin.Any?
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Demo5 {
|
||||||
|
public constructor Demo5()
|
||||||
|
private final val some: Demo5.some.<no name provided>
|
||||||
|
private final var state: kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -130,6 +130,12 @@ public class DataFlowTestGenerated extends AbstractDataFlowTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localObjectInConstructor.kt")
|
||||||
|
public void testLocalObjectInConstructor() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/localObjectInConstructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("referenceToPropertyInitializer.kt")
|
@TestMetadata("referenceToPropertyInitializer.kt")
|
||||||
public void testReferenceToPropertyInitializer() throws Exception {
|
public void testReferenceToPropertyInitializer() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.kt");
|
||||||
|
|||||||
@@ -888,6 +888,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localObjectInConstructor.kt")
|
||||||
|
public void testLocalObjectInConstructor() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/localObjectInConstructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("referenceToPropertyInitializer.kt")
|
@TestMetadata("referenceToPropertyInitializer.kt")
|
||||||
public void testReferenceToPropertyInitializer() throws Exception {
|
public void testReferenceToPropertyInitializer() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.kt");
|
||||||
|
|||||||
@@ -3600,6 +3600,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localObjectInConstructor.kt")
|
||||||
|
public void testLocalObjectInConstructor() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nestedTryFinally.kt")
|
@TestMetadata("nestedTryFinally.kt")
|
||||||
public void testNestedTryFinally() throws Exception {
|
public void testNestedTryFinally() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/nestedTryFinally.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user