diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 245c4f6a55a..35a67fec48a 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -5696,6 +5696,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturnInWhen.kt"); } + @Test + @TestMetadata("delegatedMemberProperyWriteInInit.kt") + public void testDelegatedMemberProperyWriteInInit() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt"); + } + @Test @TestMetadata("delegatedPropertyEarlyAccess.kt") public void testDelegatedPropertyEarlyAccess() throws Exception { @@ -6116,6 +6122,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt"); } + @Test + @TestMetadata("uninintializedProperyWithDirectAndDelayedInitialization.kt") + public void testUninintializedProperyWithDirectAndDelayedInitialization() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt"); + } + @Test @TestMetadata("uninitializedCompanionOfEnum_after.kt") public void testUninitializedCompanionOfEnum_after() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index c24c492b24d..edac921e509 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -5702,6 +5702,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturnInWhen.kt"); } + @Test + @TestMetadata("delegatedMemberProperyWriteInInit.kt") + public void testDelegatedMemberProperyWriteInInit() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt"); + } + @Test @TestMetadata("delegatedPropertyEarlyAccess.kt") public void testDelegatedPropertyEarlyAccess() throws Exception { @@ -6122,6 +6128,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt"); } + @Test + @TestMetadata("uninintializedProperyWithDirectAndDelayedInitialization.kt") + public void testUninintializedProperyWithDirectAndDelayedInitialization() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt"); + } + @Test @TestMetadata("uninitializedCompanionOfEnum_after.kt") public void testUninitializedCompanionOfEnum_after() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 8a9850d9bea..998256817f9 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -5696,6 +5696,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturnInWhen.kt"); } + @Test + @TestMetadata("delegatedMemberProperyWriteInInit.kt") + public void testDelegatedMemberProperyWriteInInit() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt"); + } + @Test @TestMetadata("delegatedPropertyEarlyAccess.kt") public void testDelegatedPropertyEarlyAccess() throws Exception { @@ -6116,6 +6122,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt"); } + @Test + @TestMetadata("uninintializedProperyWithDirectAndDelayedInitialization.kt") + public void testUninintializedProperyWithDirectAndDelayedInitialization() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt"); + } + @Test @TestMetadata("uninitializedCompanionOfEnum_after.kt") public void testUninitializedCompanionOfEnum_after() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt index 92f059d846c..23a51ddf5e6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt @@ -31,7 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChecker() { override fun analyze(data: PropertyInitializationInfoData, reporter: DiagnosticReporter, context: CheckerContext) { - data.checkPropertyAccesses(context, reporter) + data.checkPropertyAccesses(isForClassInitialization = false, context, reporter) } } @@ -44,15 +44,36 @@ val FirDeclaration.evaluatedInPlace: Boolean else -> true // property initializer, etc. } -@OptIn(SymbolInternals::class) -val FirPropertySymbol.requiresInitialization: Boolean - get() = this !is FirSyntheticPropertySymbol && !hasInitializer && !hasExplicitBackingField && - hasBackingField && fir.isCatchParameter != true +/** + * [isForClassInitialization] means that caller is interested in member property in the scope + * of class initialization section. In this case the fact that property has initializer does + * not mean that it's safe to access this property in any place: + * + * class A { + * val b = a // a is not initialized here + * val a = 10 + * val c = a // but initialized here + * } + */ -fun PropertyInitializationInfoData.checkPropertyAccesses(context: CheckerContext, reporter: DiagnosticReporter) { +@OptIn(SymbolInternals::class) +fun FirPropertySymbol.requiresInitialization(isForClassInitialization: Boolean): Boolean { + val hasImplicitBackingField = !hasExplicitBackingField && hasBackingField + return when { + this is FirSyntheticPropertySymbol -> false + isForClassInitialization -> hasDelegate || hasImplicitBackingField + else -> !hasInitializer && hasImplicitBackingField && fir.isCatchParameter != true + } +} + +fun PropertyInitializationInfoData.checkPropertyAccesses( + isForClassInitialization: Boolean, + context: CheckerContext, + reporter: DiagnosticReporter +) { // If a property has an initializer (or does not need one), then any reads are OK while any writes are OK // if it's a `var` and bad if it's a `val`. `FirReassignmentAndInvisibleSetterChecker` does this without a CFG. - val filtered = properties.filterTo(mutableSetOf()) { it.requiresInitialization } + val filtered = properties.filterTo(mutableSetOf()) { it.requiresInitialization(isForClassInitialization) } if (filtered.isEmpty()) return checkPropertyAccesses(graph, filtered, context, reporter, null, mutableMapOf()) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt index a9a592e556d..82936c77fd8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/PropertyInitializationInfoCollector.kt @@ -73,6 +73,18 @@ class PropertyInitializationInfoCollector( } } + override fun visitPropertyInitializerExitNode( + node: PropertyInitializerExitNode, + data: PathAwareControlFlowInfo + ): PathAwareControlFlowInfo { + // If member property initializer is empty (there are no nodes between enter and exit node) + // then property is not initialized in its declaration + // Otherwise it is + val dataForNode = visitNode(node, data) + if (node.firstPreviousNode is PropertyInitializerEnterNode) return dataForNode + return overwriteRange(dataForNode, node.fir.symbol, EventOccurrencesRange.EXACTLY_ONCE) + } + // -------------------------------------------------- // Data flows of declared/assigned variables in loops // -------------------------------------------------- diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt index 3333df1c309..83e21fe3017 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt @@ -47,12 +47,12 @@ object FirMemberPropertiesChecker : FirClassChecker() { private fun FirClass.collectInitializationInfo(context: CheckerContext, reporter: DiagnosticReporter): PropertyInitializationInfo? { val graph = (this as? FirControlFlowGraphOwner)?.controlFlowGraphReference?.controlFlowGraph ?: return null val memberPropertySymbols = declarations.mapNotNullTo(mutableSetOf()) { - (it.symbol as? FirPropertySymbol)?.takeIf { symbol -> symbol.requiresInitialization } + (it.symbol as? FirPropertySymbol)?.takeIf { symbol -> symbol.requiresInitialization(isForClassInitialization = true) } } if (memberPropertySymbols.isEmpty()) return null // TODO: merge with `FirPropertyInitializationAnalyzer` for fewer passes. val data = PropertyInitializationInfoData(memberPropertySymbols, symbol, graph) - data.checkPropertyAccesses(context, reporter) + data.checkPropertyAccesses(isForClassInitialization = true, context, reporter) return data.getValue(graph.exitNode)[NormalPath] } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt index 99976c4d4d5..efb2f2942e0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt @@ -138,7 +138,8 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() if (property.isVar) return // Assignments of uninitialized `val`s must be checked via CFG, since the first one is OK. // See `FirPropertyInitializationAnalyzer` for locals and `FirMemberPropertiesChecker` for backing fields in initializers. - if (property.requiresInitialization && (property.isLocal || isInOwnersInitializer(expression.dispatchReceiver, context))) return + if (property.isLocal && property.requiresInitialization(isForClassInitialization = false)) return + if (isInOwnersInitializer(expression.dispatchReceiver, context) && property.requiresInitialization(isForClassInitialization = true)) return reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, property, context) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt index aacd6ff0889..45d5f76619e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt @@ -43,7 +43,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() { } } - private class ReassignedVariableCollector(val data: PropertyInitializationInfoData, ) : ControlFlowGraphVisitorVoid() { + private class ReassignedVariableCollector(val data: PropertyInitializationInfoData) : ControlFlowGraphVisitorVoid() { private val reassigned = mutableSetOf() override fun visitNode(node: CFGNode<*>) {} @@ -51,7 +51,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() { override fun visitVariableAssignmentNode(node: VariableAssignmentNode) { val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: return if (symbol.isVar && symbol.source?.kind !is KtFakeSourceElementKind && symbol in data.properties && - (!symbol.requiresInitialization || data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) + (!symbol.requiresInitialization(isForClassInitialization = data.graph.kind == ControlFlowGraph.Kind.Class) || data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) ) { reassigned.add(symbol) } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt index c8c711c8b1c..07863a93c87 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.fir.kt @@ -255,8 +255,8 @@ class Outer() { } class ForwardAccessToBackingField() { //kt-147 - val a = a // error - val b = c // error + val a = a // error + val b = c // error val c = 1 } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.fir.kt new file mode 100644 index 00000000000..93254ac730c --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.fir.kt @@ -0,0 +1,40 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty + +interface Delegate { + operator fun getValue(thisRef: Any?, property: KProperty<*>): V = null!! + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {} +} + +fun delegate(): Delegate = null!! +fun consume(x: Any?) {} + +class A { + init { + consume(x) + x = 10 + } + + val x: Int by delegate() + + init { + x = 10 + consume(x) + } +} + +class B { + init { + consume(x) + x = 10 + } + + var x: Int by delegate() + + init { + x = 10 + consume(x) + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt new file mode 100644 index 00000000000..528e77657ed --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt @@ -0,0 +1,40 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty + +interface Delegate { + operator fun getValue(thisRef: Any?, property: KProperty<*>): V = null!! + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {} +} + +fun delegate(): Delegate = null!! +fun consume(x: Any?) {} + +class A { + init { + consume(x) + x = 10 + } + + val x: Int by delegate() + + init { + x = 10 + consume(x) + } +} + +class B { + init { + consume(x) + x = 10 + } + + var x: Int by delegate() + + init { + x = 10 + consume(x) + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.fir.kt index 25ca351fb4f..c9b2fd3f520 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.fir.kt @@ -1,4 +1,4 @@ -// See also KT-10869: Accessing lazy properties from init causes IllegalArgumentException +// ISSUE: KT-10869, KT-56682 import kotlin.reflect.KProperty @@ -9,14 +9,14 @@ class CustomDelegate { class Kaboom() { // Here and below we should have errors for simple AND delegated init { - delegated.hashCode() - simple.hashCode() + delegated.hashCode() + simple.hashCode() withGetter.hashCode() } - val other = delegated + val other = delegated - val another = simple + val another = simple val something = withGetter diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.kt index 2d1124a13da..b8ff9cb0e32 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedPropertyEarlyAccess.kt @@ -1,4 +1,4 @@ -// See also KT-10869: Accessing lazy properties from init causes IllegalArgumentException +// ISSUE: KT-10869, KT-56682 import kotlin.reflect.KProperty diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.fir.kt deleted file mode 100644 index 2f32717d596..00000000000 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -//KT-897 Don't allow assignment to a property before it is defined - -package kt897 - -class A() { - init { - i = 11 - } - val i : Int? = null // must be an error - - init { - j = 1 - } - var j : Int = 2 - - init { - k = 3 - } - val k : Int -} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.kt index eb279e36d50..0f56423a5a9 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt897.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //KT-897 Don't allow assignment to a property before it is defined package kt897 diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.fir.kt new file mode 100644 index 00000000000..2f049b0656b --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.fir.kt @@ -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 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) + } + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt index 72518ea0657..3cb2bd13754 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/localObjectInConstructor.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL fun println(obj: Any?) = obj class Demo0 { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.fir.kt index 293091f3571..07b6585530b 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/referenceToPropertyInitializer.fir.kt @@ -11,22 +11,22 @@ class TestFunctionLiteral { open class A(val a: A) class TestObjectLiteral { - val obj: A = object: A(obj) { + val obj: A = object: A(obj) { init { - val x = obj + val x = obj } fun foo() { val y = obj } } - val obj1: A = l@ ( object: A(obj1) { + val obj1: A = l@ ( object: A(obj1) { init { - val x = obj1 + val x = obj1 } fun foo() = obj1 }) } class TestOther { - val x: Int = x + 1 + val x: Int = x + 1 } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/repeatUnitializedErrorOnlyForLocalVars.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/repeatUnitializedErrorOnlyForLocalVars.fir.kt index 3fbfbe21626..be28e872c2e 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/repeatUnitializedErrorOnlyForLocalVars.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/repeatUnitializedErrorOnlyForLocalVars.fir.kt @@ -4,8 +4,8 @@ val a : Int = b val b : Int = a + b class C { - val a : Int = b - val b : Int = a + b + val a : Int = b + val b : Int = a + b } fun foo() { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt new file mode 100644 index 00000000000..f5588762ddf --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt @@ -0,0 +1,18 @@ +// FIR_IDENTICAL +// ISSUE: KT-56678 + +class A { + val b = a + val a = 1 + val c = a +} + +class B { + val b = a + val a: Int + val c = a + init { + a = 1 + } + val d = a +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/kt48546.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/kt48546.fir.kt index 81e341b1d4f..19138f21642 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/kt48546.fir.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/kt48546.fir.kt @@ -4,7 +4,7 @@ object DelegateTest { var result = "" val f by lazy { - result += f.toString() // Compiler crash + result += f.toString() // Compiler crash "hello" } } @@ -12,7 +12,7 @@ object DelegateTest { object DelegateTest2 { var result = "" val f by lazy { - result += f + result += f "hello" } } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/kt48546Strict.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/kt48546Strict.fir.kt index 9d84d24a098..82d551054b1 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/kt48546Strict.fir.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/kt48546Strict.fir.kt @@ -5,7 +5,7 @@ object DelegateTest { var result = "" val f by lazy { - result += f.toString() // Compiler crash + result += f.toString() // Compiler crash "hello" } } @@ -13,7 +13,7 @@ object DelegateTest { object DelegateTest2 { var result = "" val f by lazy { - result += f + result += f "hello" } } diff --git a/compiler/testData/diagnostics/tests/delegation/kt48546.fir.kt b/compiler/testData/diagnostics/tests/delegation/kt48546.fir.kt index b04a5fa33ab..0c28d00b081 100644 --- a/compiler/testData/diagnostics/tests/delegation/kt48546.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/kt48546.fir.kt @@ -3,7 +3,7 @@ object DelegateTest { var result = "" val f by lazy { - result += f.toString() // Compiler crash + result += f.toString() // Compiler crash "hello" } } diff --git a/compiler/testData/diagnostics/tests/regressions/Jet81.fir.kt b/compiler/testData/diagnostics/tests/regressions/Jet81.fir.kt index 379ca95c824..cc9a5448b11 100644 --- a/compiler/testData/diagnostics/tests/regressions/Jet81.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/Jet81.fir.kt @@ -3,7 +3,7 @@ class Test { private val y = object { - val a = y; + val a = y; } val z = y.a; @@ -17,9 +17,9 @@ object A { class Test2 { private val a = object { init { - b + 1 + b + 1 } - val x = b + val x = b val y = 1 } diff --git a/compiler/testData/diagnostics/tests/regressions/kt328.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt328.fir.kt index 5755cafeedb..9632b69d7d9 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt328.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt328.fir.kt @@ -12,7 +12,7 @@ fun bar2() = { //properties //in a class class A() { - val x = { x } + val x = { x } } //in a package diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithPrimary.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithPrimary.fir.kt index da1868491b7..eb19a21c7f2 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithPrimary.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithPrimary.fir.kt @@ -3,7 +3,7 @@ class A(val w: Int) { val x: Int val useUnitialized = x + y + - v + v var y: Int val v = -1 val useInitialized = useUnitialized + v + w diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithoutPrimary.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithoutPrimary.fir.kt index cc283d39bc6..82a49f19a8f 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithoutPrimary.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/useOfPropertiesWithoutPrimary.fir.kt @@ -3,7 +3,7 @@ class A { val x: Int val useUnitialized = x + // reported on each secondary constructor y + - v + v var y: Int val v = -1 diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index d15a367f4ae..fb3739549bd 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -5702,6 +5702,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturnInWhen.kt"); } + @Test + @TestMetadata("delegatedMemberProperyWriteInInit.kt") + public void testDelegatedMemberProperyWriteInInit() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/delegatedMemberProperyWriteInInit.kt"); + } + @Test @TestMetadata("delegatedPropertyEarlyAccess.kt") public void testDelegatedPropertyEarlyAccess() throws Exception { @@ -6122,6 +6128,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt"); } + @Test + @TestMetadata("uninintializedProperyWithDirectAndDelayedInitialization.kt") + public void testUninintializedProperyWithDirectAndDelayedInitialization() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninintializedProperyWithDirectAndDelayedInitialization.kt"); + } + @Test @TestMetadata("uninitializedCompanionOfEnum_after.kt") public void testUninitializedCompanionOfEnum_after() throws Exception {