diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/PseudocodeVariablesData.java b/compiler/frontend/src/org/jetbrains/kotlin/cfg/PseudocodeVariablesData.java index 9798d3d54e8..76d167fc53e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/PseudocodeVariablesData.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/PseudocodeVariablesData.java @@ -126,7 +126,7 @@ public class PseudocodeVariablesData { final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariableDataCollector.getLexicalScopeVariableInfo(); return pseudocodeVariableDataCollector.collectData( - FORWARD, /*mergeDataWithLocalDeclarations=*/ false, + FORWARD, /*mergeDataWithLocalDeclarations=*/ true, new InstructionDataMergeStrategy() { @NotNull @Override diff --git a/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions index a91884c040a..1537bde073e 100644 --- a/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions +++ b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions @@ -34,27 +34,27 @@ sink: } --------------------- L3: - 3 INIT: in: {} out: {} - v(x: Int) INIT: in: {} out: {x=D} - magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {x=D} out: {x=D} - w(x|) INIT: in: {x=D} out: {x=ID} - 4 mark(val y = x + a use(a)) INIT: in: {x=ID} out: {x=ID} - v(val y = x + a) INIT: in: {x=ID} out: {x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ} - r(x) -> INIT: in: {x=ID, y=D} out: {x=ID, y=D} USE: in: {a=READ} out: {a=READ, x=READ} + 3 INIT: in: {a=ID, f=D} out: {a=ID, f=D} + v(x: Int) INIT: in: {a=ID, f=D} out: {a=ID, f=D, x=D} + magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {a=ID, f=D, x=D} out: {a=ID, f=D, x=D} + w(x|) INIT: in: {a=ID, f=D, x=D} out: {a=ID, f=D, x=ID} + 4 mark(val y = x + a use(a)) INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID} + v(val y = x + a) INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ} + r(x) -> INIT: in: {a=ID, f=D, x=ID, y=D} out: {a=ID, f=D, x=ID, y=D} USE: in: {a=READ} out: {a=READ, x=READ} r(a) -> mark(x + a) call(x + a, plus|, ) -> - w(y|) INIT: in: {x=ID, y=D} out: {x=ID, y=ID} USE: in: {a=READ} out: {a=READ} - r(a) -> INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {} out: {a=READ} + w(y|) INIT: in: {a=ID, f=D, x=ID, y=D} out: {a=ID, f=D, x=ID, y=ID} USE: in: {a=READ} out: {a=READ} + r(a) -> INIT: in: {a=ID, f=D, x=ID, y=ID} out: {a=ID, f=D, x=ID, y=ID} USE: in: {} out: {a=READ} mark(use(a)) call(use(a), use|) -> - 3 ret(*|) L4 INIT: in: {x=ID} out: {x=ID} + 3 ret(*|) L4 INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID} L4: error: INIT: in: {} out: {} sink: - INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} + INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID} USE: in: {} out: {} ===================== == use == fun use(vararg a: Any?) = a diff --git a/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.instructions b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.instructions new file mode 100644 index 00000000000..5fcde701ea8 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.instructions @@ -0,0 +1,60 @@ +== bar == +fun bar(f: () -> Unit) = f() +--------------------- +L0: + 1 INIT: in: {} out: {} + v(f: () -> Unit) INIT: in: {} out: {f=D} + magic[FAKE_INITIALIZER](f: () -> Unit) -> INIT: in: {f=D} out: {f=D} + w(f|) INIT: in: {f=D} out: {f=ID} USE: in: {f=READ} out: {f=READ} + r(f) -> INIT: in: {f=ID} out: {f=ID} USE: in: {} out: {f=READ} + mark(f()) + call(f(), invoke|) -> + ret(*|) L1 +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {f=ID} out: {f=ID} USE: in: {} out: {} +===================== +== foo == +fun foo() { + var v: Any + bar { v.hashCode() } +} +--------------------- +L0: + 1 INIT: in: {} out: {} USE: in: {} out: {} + 2 mark({ var v: Any bar { v.hashCode() } }) + v(var v: Any) INIT: in: {} out: {v=D} + mark({ v.hashCode() }) INIT: in: {v=D} out: {v=D} + jmp?(L2) + d({ v.hashCode() }) USE: in: {v=READ} out: {v=READ} +L2 [after local declaration]: + r({ v.hashCode() }) -> + mark(bar { v.hashCode() }) + call(bar { v.hashCode() }, bar|) -> +L1: + 1 INIT: in: {} out: {} +error: + +sink: + USE: in: {} out: {} +===================== +== anonymous_0 == +{ v.hashCode() } +--------------------- +L3: + 3 INIT: in: {v=D} out: {v=D} + 4 mark(v.hashCode()) + mark(v.hashCode()) USE: in: {v=READ} out: {v=READ} + r(v) -> USE: in: {} out: {v=READ} + mark(hashCode()) + call(hashCode(), hashCode|) -> +L4: + 3 +error: + INIT: in: {} out: {} +sink: + INIT: in: {v=D} out: {v=D} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.kt b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.kt new file mode 100644 index 00000000000..9c6fef2ec46 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.kt @@ -0,0 +1,6 @@ +fun bar(f: () -> Unit) = f() + +fun foo() { + var v: Any + bar { v.hashCode() } +} diff --git a/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.values b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.values new file mode 100644 index 00000000000..fe54469457f --- /dev/null +++ b/compiler/testData/cfg-variables/basic/UseUninitializedInLambda.values @@ -0,0 +1,25 @@ +== bar == +fun bar(f: () -> Unit) = f() +--------------------- + : {<: () -> Unit} NEW: magic[FAKE_INITIALIZER](f: () -> Unit) -> +f : {<: () -> Unit} NEW: r(f) -> +f() : Unit NEW: call(f(), invoke|) -> +===================== +== foo == +fun foo() { + var v: Any + bar { v.hashCode() } +} +--------------------- +{ v.hashCode() } : {<: () -> Unit} NEW: r({ v.hashCode() }) -> +bar { v.hashCode() } : * NEW: call(bar { v.hashCode() }, bar|) -> +{ var v: Any bar { v.hashCode() } } : * COPY +===================== +== anonymous_0 == +{ v.hashCode() } +--------------------- +v : {<: Any} NEW: r(v) -> +hashCode() : * NEW: call(hashCode(), hashCode|) -> +v.hashCode() : * COPY +v.hashCode() : * COPY +===================== diff --git a/compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.instructions b/compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.instructions index 3429c27ce26..ddd4d2e8d87 100644 --- a/compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.instructions +++ b/compiler/testData/cfg-variables/bugs/referenceToPropertyInitializer.instructions @@ -27,20 +27,20 @@ sink: } --------------------- L3: - 2 INIT: in: {} out: {} - v(x: Int) INIT: in: {} out: {x=D} - magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {x=D} out: {x=D} - w(x|) INIT: in: {x=D} out: {x=ID} - 3 mark(sum(x - 1) + x) INIT: in: {x=ID} out: {x=ID} - magic[IMPLICIT_RECEIVER](sum) -> USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ} - r(sum|) -> USE: in: {x=READ} out: {sum=READ, x=READ} + 2 INIT: in: {sum=D} out: {sum=D} + v(x: Int) INIT: in: {sum=D} out: {sum=D, x=D} + magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {sum=D, x=D} out: {sum=D, x=D} + w(x|) 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} + magic[IMPLICIT_RECEIVER](sum) -> USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ} + r(sum|) -> USE: in: {x=READ} out: {sum=READ, x=READ} r(x) -> r(1) -> mark(x - 1) call(x - 1, minus|, ) -> mark(sum(x - 1)) - call(sum(x - 1), invoke|, ) -> USE: in: {x=READ} out: {x=READ} - r(x) -> USE: in: {} out: {x=READ} + call(sum(x - 1), invoke|, ) -> USE: in: {x=READ} out: {x=READ} + r(x) -> USE: in: {} out: {x=READ} mark(sum(x - 1) + x) call(sum(x - 1) + x, plus|, ) -> 2 ret(*|) L4 @@ -49,7 +49,7 @@ L4: error: INIT: in: {} out: {} sink: - INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} + INIT: in: {sum=D, x=ID} out: {sum=D, x=ID} USE: in: {} out: {} ===================== == A == open class A(val a: A) @@ -109,18 +109,18 @@ fun foo() { } --------------------- L3: - 2 INIT: in: {} out: {} + 2 INIT: in: {obj=D} out: {obj=D} 3 mark({ val y = obj }) - v(val y = obj) INIT: in: {} out: {y=D} - magic[IMPLICIT_RECEIVER](obj) -> INIT: in: {y=D} out: {y=D} USE: in: {obj=READ} out: {obj=READ} - r(obj|) -> USE: in: {} out: {obj=READ} - w(y|) INIT: in: {y=D} out: {y=ID} + v(val y = obj) INIT: in: {obj=D} out: {obj=D, y=D} + magic[IMPLICIT_RECEIVER](obj) -> INIT: in: {obj=D, y=D} out: {obj=D, y=D} USE: in: {obj=READ} out: {obj=READ} + r(obj|) -> USE: in: {} out: {obj=READ} + w(y|) INIT: in: {obj=D, y=D} out: {obj=D, y=ID} L4: - 2 INIT: in: {} out: {} + 2 INIT: in: {obj=D} out: {obj=D} error: - + INIT: in: {} out: {} sink: - USE: in: {} out: {} + INIT: in: {obj=D} out: {obj=D} USE: in: {} out: {} ===================== == TestOther == class TestOther { diff --git a/compiler/testData/cfg-variables/lexicalScopes/functionLiteralScope.instructions b/compiler/testData/cfg-variables/lexicalScopes/functionLiteralScope.instructions index a2961cd1354..a122fe549a2 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/functionLiteralScope.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/functionLiteralScope.instructions @@ -38,21 +38,21 @@ sink: } --------------------- L3: - 3 INIT: in: {} out: {} - v(x: Int) INIT: in: {} out: {x=D} - magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {x=D} out: {x=D} - w(x|) INIT: in: {x=D} out: {x=ID} - 4 mark(val a = x + b) INIT: in: {x=ID} out: {x=ID} - v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} - r(x) -> INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ} out: {b=READ, x=READ} - r(b) -> USE: in: {} out: {b=READ} + 3 INIT: in: {b=ID, f=D} out: {b=ID, f=D} + v(x: Int) INIT: in: {b=ID, f=D} out: {b=ID, f=D, x=D} + magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {b=ID, f=D, x=D} out: {b=ID, f=D, x=D} + w(x|) INIT: in: {b=ID, f=D, x=D} out: {b=ID, f=D, x=ID} + 4 mark(val a = x + b) INIT: in: {b=ID, f=D, x=ID} out: {b=ID, f=D, x=ID} + v(val a = x + b) INIT: in: {b=ID, f=D, x=ID} out: {a=D, b=ID, f=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} + r(x) -> INIT: in: {a=D, b=ID, f=D, x=ID} out: {a=D, b=ID, f=D, x=ID} USE: in: {b=READ} out: {b=READ, x=READ} + r(b) -> USE: in: {} out: {b=READ} mark(x + b) call(x + b, plus|, ) -> - w(a|) INIT: in: {a=D, x=ID} out: {a=ID, x=ID} + w(a|) INIT: in: {a=D, b=ID, f=D, x=ID} out: {a=ID, b=ID, f=D, x=ID} L4: - 3 INIT: in: {x=ID} out: {x=ID} + 3 INIT: in: {b=ID, f=D, x=ID} out: {b=ID, f=D, x=ID} error: INIT: in: {} out: {} sink: - INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} + INIT: in: {b=ID, f=D, x=ID} out: {b=ID, f=D, x=ID} USE: in: {} out: {} ===================== diff --git a/compiler/testData/cfg-variables/lexicalScopes/localClass.instructions b/compiler/testData/cfg-variables/lexicalScopes/localClass.instructions index e5de27fae68..405f085c8e8 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/localClass.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/localClass.instructions @@ -43,16 +43,16 @@ fun foo() { } --------------------- L3: - 3 INIT: in: {} out: {} + 3 INIT: in: {x=ID} out: {x=ID} 4 mark({ val b = x }) - v(val b = x) INIT: in: {} out: {b=D} - magic[IMPLICIT_RECEIVER](x) -> INIT: in: {b=D} out: {b=D} USE: in: {x=READ} out: {x=READ} - r(x|) -> USE: in: {} out: {x=READ} - w(b|) INIT: in: {b=D} out: {b=ID} + v(val b = x) INIT: in: {x=ID} out: {b=D, x=ID} + magic[IMPLICIT_RECEIVER](x) -> INIT: in: {b=D, x=ID} out: {b=D, x=ID} USE: in: {x=READ} out: {x=READ} + r(x|) -> USE: in: {} out: {x=READ} + w(b|) INIT: in: {b=D, x=ID} out: {b=ID, x=ID} L4: - 3 INIT: in: {} out: {} + 3 INIT: in: {x=ID} out: {x=ID} error: - + INIT: in: {} out: {} sink: - USE: in: {} out: {} + INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} ===================== diff --git a/compiler/testData/cfg-variables/lexicalScopes/localFunctionScope.instructions b/compiler/testData/cfg-variables/lexicalScopes/localFunctionScope.instructions index cd3682a6d9d..869e81bc0e2 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/localFunctionScope.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/localFunctionScope.instructions @@ -34,21 +34,21 @@ fun local(x: Int) { } --------------------- L3: - 3 INIT: in: {} out: {} - v(x: Int) INIT: in: {} out: {x=D} - magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {x=D} out: {x=D} - w(x|) INIT: in: {x=D} out: {x=ID} - 4 mark({ val a = x + b }) INIT: in: {x=ID} out: {x=ID} - v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} - r(x) -> INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ} out: {b=READ, x=READ} - r(b) -> USE: in: {} out: {b=READ} + 3 INIT: in: {b=ID} out: {b=ID} + v(x: Int) INIT: in: {b=ID} out: {b=ID, x=D} + magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {b=ID, x=D} out: {b=ID, x=D} + w(x|) INIT: in: {b=ID, x=D} out: {b=ID, x=ID} + 4 mark({ val a = x + b }) INIT: in: {b=ID, x=ID} out: {b=ID, x=ID} + v(val a = x + b) INIT: in: {b=ID, x=ID} out: {a=D, b=ID, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} + r(x) -> INIT: in: {a=D, b=ID, x=ID} out: {a=D, b=ID, x=ID} USE: in: {b=READ} out: {b=READ, x=READ} + r(b) -> USE: in: {} out: {b=READ} mark(x + b) call(x + b, plus|, ) -> - w(a|) INIT: in: {a=D, x=ID} out: {a=ID, x=ID} + w(a|) INIT: in: {a=D, b=ID, x=ID} out: {a=ID, b=ID, x=ID} L4: - 3 INIT: in: {x=ID} out: {x=ID} + 3 INIT: in: {b=ID, x=ID} out: {b=ID, x=ID} error: INIT: in: {} out: {} sink: - INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} + INIT: in: {b=ID, x=ID} out: {b=ID, x=ID} USE: in: {} out: {} ===================== \ No newline at end of file diff --git a/compiler/testData/cfg-variables/lexicalScopes/localFunctionScopeWithoutBody.instructions b/compiler/testData/cfg-variables/lexicalScopes/localFunctionScopeWithoutBody.instructions index 0fad9e0baef..04119bebf3b 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/localFunctionScopeWithoutBody.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/localFunctionScopeWithoutBody.instructions @@ -30,12 +30,12 @@ sink: fun local(x: Int) = x + b --------------------- L3: - 3 INIT: in: {} out: {} - v(x: Int) INIT: in: {} out: {x=D} - magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {x=D} out: {x=D} - w(x|) INIT: in: {x=D} out: {x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} - r(x) -> INIT: in: {x=ID} out: {x=ID} USE: in: {b=READ} out: {b=READ, x=READ} - r(b) -> USE: in: {} out: {b=READ} + 3 INIT: in: {b=ID} out: {b=ID} + v(x: Int) INIT: in: {b=ID} out: {b=ID, x=D} + magic[FAKE_INITIALIZER](x: Int) -> INIT: in: {b=ID, x=D} out: {b=ID, x=D} + w(x|) INIT: in: {b=ID, x=D} out: {b=ID, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ} + r(x) -> INIT: in: {b=ID, x=ID} out: {b=ID, x=ID} USE: in: {b=READ} out: {b=READ, x=READ} + r(b) -> USE: in: {} out: {b=READ} mark(x + b) call(x + b, plus|, ) -> ret(*|) L4 @@ -44,5 +44,5 @@ L4: error: INIT: in: {} out: {} sink: - INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} + INIT: in: {b=ID, x=ID} out: {b=ID, x=ID} USE: in: {} out: {} ===================== \ No newline at end of file diff --git a/compiler/testData/cfg-variables/lexicalScopes/objectLiteralScope.instructions b/compiler/testData/cfg-variables/lexicalScopes/objectLiteralScope.instructions index 12dd55250b3..04384b957b6 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/objectLiteralScope.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/objectLiteralScope.instructions @@ -43,15 +43,15 @@ fun foo() { } --------------------- L3: - 3 INIT: in: {} out: {} + 3 INIT: in: {bar=D} out: {bar=D} 4 mark({ val a = 2 }) - v(val a = 2) INIT: in: {} out: {a=D} - r(2) -> INIT: in: {a=D} out: {a=D} - w(a|) INIT: in: {a=D} out: {a=ID} + v(val a = 2) INIT: in: {bar=D} out: {a=D, bar=D} + r(2) -> INIT: in: {a=D, bar=D} out: {a=D, bar=D} + w(a|) INIT: in: {a=D, bar=D} out: {a=ID, bar=D} L4: - 3 INIT: in: {} out: {} + 3 INIT: in: {bar=D} out: {bar=D} error: - + INIT: in: {} out: {} sink: - USE: in: {} out: {} + INIT: in: {bar=D} out: {bar=D} USE: in: {} out: {} ===================== \ No newline at end of file diff --git a/compiler/testData/cfg-variables/lexicalScopes/propertyAccessorScope.instructions b/compiler/testData/cfg-variables/lexicalScopes/propertyAccessorScope.instructions index e269cd5fdbf..79bd6c32213 100644 --- a/compiler/testData/cfg-variables/lexicalScopes/propertyAccessorScope.instructions +++ b/compiler/testData/cfg-variables/lexicalScopes/propertyAccessorScope.instructions @@ -15,18 +15,18 @@ L0: 1 INIT: in: {} out: {} 2 mark({ class A { var a : Int get() { return field } set(v: Int) { field = v } } }) v(var a : Int get() { return field } set(v: Int) { field = v }) INIT: in: {} out: {a=D} - jmp?(L2) 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 }) USE: in: {field=READ} out: {field=READ} + jmp?(L2) 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 }) USE: in: {field=READ} out: {field=READ} L2 [after local declaration]: jmp?(L5) - d(set(v: Int) { field = v }) USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ} + d(set(v: Int) { field = v }) INIT: in: {a=D, field=I} out: {a=D, field=I} USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ} L1: L5 [after local declaration]: 1 INIT: in: {} out: {} error: sink: - USE: in: {} out: {} + INIT: in: {field=I} out: {field=I} USE: in: {} out: {} ===================== == get_a == get() { @@ -34,16 +34,16 @@ get() { } --------------------- L3: - 3 INIT: in: {} out: {} - 4 mark({ return field }) USE: in: {field=READ} out: {field=READ} - r(field) -> USE: in: {} out: {field=READ} + 3 INIT: in: {a=D} out: {a=D} + 4 mark({ return field }) USE: in: {field=READ} out: {field=READ} + r(field) -> USE: in: {} out: {field=READ} ret(*|) L4 L4: 3 error: - + INIT: in: {} out: {} sink: - USE: in: {} out: {} + INIT: in: {a=D} out: {a=D} USE: in: {} out: {} ===================== == set_a == set(v: Int) { @@ -51,17 +51,17 @@ set(v: Int) { } --------------------- L6: - 3 INIT: in: {} out: {} - v(v: Int) INIT: in: {} out: {v=D} - magic[FAKE_INITIALIZER](v: Int) -> INIT: in: {v=D} out: {v=D} - w(v|) INIT: in: {v=D} out: {v=ID} - 4 mark({ field = v }) INIT: in: {v=ID} out: {v=ID} USE: in: {field=ONLY_WRITTEN_NEVER_READ, v=READ} out: {field=ONLY_WRITTEN_NEVER_READ, v=READ} - r(v) -> USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ, v=READ} - w(field|) INIT: in: {v=ID} out: {field=I, v=ID} USE: in: {} out: {field=ONLY_WRITTEN_NEVER_READ} + 3 INIT: in: {a=D} out: {a=D} + v(v: Int) INIT: in: {a=D} out: {a=D, v=D} + magic[FAKE_INITIALIZER](v: Int) -> INIT: in: {a=D, v=D} out: {a=D, v=D} + w(v|) INIT: in: {a=D, v=D} out: {a=D, v=ID} + 4 mark({ field = v }) INIT: in: {a=D, v=ID} out: {a=D, v=ID} USE: in: {field=ONLY_WRITTEN_NEVER_READ, v=READ} out: {field=ONLY_WRITTEN_NEVER_READ, v=READ} + r(v) -> USE: in: {field=ONLY_WRITTEN_NEVER_READ} out: {field=ONLY_WRITTEN_NEVER_READ, v=READ} + w(field|) INIT: in: {a=D, v=ID} out: {a=D, field=I, v=ID} USE: in: {} out: {field=ONLY_WRITTEN_NEVER_READ} L7: - 3 INIT: in: {field=I, v=ID} out: {field=I, v=ID} + 3 INIT: in: {a=D, field=I, v=ID} out: {a=D, field=I, v=ID} error: INIT: in: {} out: {} sink: - INIT: in: {field=I, v=ID} out: {field=I, v=ID} USE: in: {} out: {} + INIT: in: {a=D, field=I, v=ID} out: {a=D, field=I, v=ID} USE: in: {} out: {} ===================== diff --git a/compiler/testData/codegen/box/classes/kt1120.kt b/compiler/testData/codegen/box/classes/kt1120.kt index 54cb4d59c4d..7b310d46fde 100644 --- a/compiler/testData/codegen/box/classes/kt1120.kt +++ b/compiler/testData/codegen/box/classes/kt1120.kt @@ -1,8 +1,9 @@ object RefreshQueue { + val any = Any() val workerThread: Thread = Thread(object : Runnable { override fun run() { - val a = workerThread - val b = RefreshQueue.workerThread + val a = any + val b = RefreshQueue.any if (a != b) throw AssertionError() } }) diff --git a/compiler/testData/codegen/box/properties/kt1159.kt b/compiler/testData/codegen/box/properties/kt1159.kt index 35f70f4d784..2c0a080981a 100644 --- a/compiler/testData/codegen/box/properties/kt1159.kt +++ b/compiler/testData/codegen/box/properties/kt1159.kt @@ -1,7 +1,10 @@ public object RefreshQueue { + + private val any = Any() + private val workerThread: Thread = Thread(object : Runnable { override fun run() { - workerThread.isInterrupted() + any.hashCode() } }); diff --git a/compiler/testData/diagnostics/tests/annotations/kt1860-negative.kt b/compiler/testData/diagnostics/tests/annotations/kt1860-negative.kt index de01f6eedc5..dcff8916ab7 100644 --- a/compiler/testData/diagnostics/tests/annotations/kt1860-negative.kt +++ b/compiler/testData/diagnostics/tests/annotations/kt1860-negative.kt @@ -3,7 +3,7 @@ fun foo(@varargs f : Int) {} var bar : Int = 1 set(@varargs v) {} -val x : (Int) -> Int = {@varargs x : Int -> x} +val x : (Int) -> Int = {@varargs x : Int -> x} class Hello(@varargs args: Any) { } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/kt1860-positive.kt b/compiler/testData/diagnostics/tests/annotations/kt1860-positive.kt index 9cd17e933f4..3c607124e81 100644 --- a/compiler/testData/diagnostics/tests/annotations/kt1860-positive.kt +++ b/compiler/testData/diagnostics/tests/annotations/kt1860-positive.kt @@ -6,7 +6,7 @@ fun foo(@test f : Int) {} var bar : Int = 1 set(@test v) {} -val x : (Int) -> Int = {@test x : Int -> x} // todo fix parser annotation on lambda parameter +val x : (Int) -> Int = {@test x : Int -> x} // todo fix parser annotation on lambda parameter class Hello(@test args: Any) { } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt index 52515759ca8..979ac9e3272 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt @@ -271,7 +271,7 @@ fun foo() { z = 3 } fun foo() { - y = 10 + y = 10 z = 13 } } @@ -290,7 +290,7 @@ class TestObjectExpression() { x = 1 } fun inner1() { - y = 101 + y = 101 a = 231 } fun inner2() { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.kt new file mode 100644 index 00000000000..b1c8a673971 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.kt @@ -0,0 +1,8 @@ +fun foo() { + var x: Int + fun bar() { + x = 42 + } + x.hashCode() + bar() +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.kt index 07b6585530b..56af736b6d0 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.kt @@ -3,9 +3,9 @@ package o class TestFunctionLiteral { val sum: (Int) -> Int = { x: Int -> - sum(x - 1) + x + sum(x - 1) + x } - val foo: () -> Unit = l@ ({ foo() }) + val foo: () -> Unit = l@ ({ foo() }) } open class A(val a: A) @@ -16,14 +16,14 @@ class TestObjectLiteral { val x = obj } fun foo() { - val y = obj + val y = obj } } val obj1: A = l@ ( object: A(obj1) { init { val x = obj1 } - fun foo() = obj1 + fun foo() = obj1 }) } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.kt new file mode 100644 index 00000000000..1b99ba205b8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.kt @@ -0,0 +1,6 @@ +fun bar(f: () -> Unit) = f() + +fun foo() { + var v: Any + bar { v.hashCode() } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.txt new file mode 100644 index 00000000000..6875e6e4039 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.txt @@ -0,0 +1,4 @@ +package + +public fun bar(/*0*/ f: () -> kotlin.Unit): kotlin.Unit +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/regressions/kt328.kt b/compiler/testData/diagnostics/tests/regressions/kt328.kt index 7683337e73e..818b2bafefa 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt328.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt328.kt @@ -11,11 +11,11 @@ fun bar2() = { //properties //in a class class A() { - val x = { x } + val x = { x } } //in a package -val x = { x } +val x = { x } //KT-787 AssertionError on code 'val x = x' val z = z diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/DataFlowTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/DataFlowTestGenerated.java index ef5177d19df..c7fe10fd59f 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/DataFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/DataFlowTestGenerated.java @@ -61,6 +61,12 @@ public class DataFlowTestGenerated extends AbstractDataFlowTest { doTest(fileName); } + @TestMetadata("UseUninitializedInLambda.kt") + public void testUseUninitializedInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/basic/UseUninitializedInLambda.kt"); + doTest(fileName); + } + @TestMetadata("VariablesInitialization.kt") public void testVariablesInitialization() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/basic/VariablesInitialization.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java index 04aab0aca88..86e54c9ec04 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java @@ -777,6 +777,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest { doTest(fileName); } + @TestMetadata("UseUninitializedInLambda.kt") + public void testUseUninitializedInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/basic/UseUninitializedInLambda.kt"); + doTest(fileName); + } + @TestMetadata("VariablesInitialization.kt") public void testVariablesInitialization() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg-variables/basic/VariablesInitialization.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index cb66f4fa937..e23244db858 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2745,6 +2745,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("initializationInLambda.kt") + public void testInitializationInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLambda.kt"); + doTest(fileName); + } + @TestMetadata("kt1001.kt") public void testKt1001() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1001.kt"); @@ -2991,6 +2997,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("useUninitializedInLambda.kt") + public void testUseUninitializedInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/useUninitializedInLambda.kt"); + doTest(fileName); + } + @TestMetadata("varInitializationInIfInCycle.kt") public void testVarInitializationInIfInCycle() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/varInitializationInIfInCycle.kt");