diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 3eff79b88d4..9486dd32525 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -69,9 +69,9 @@ public class JetControlFlowProcessor { private Pseudocode generate(@NotNull JetDeclaration subroutine) { builder.enterSubroutine(subroutine); + CFPVisitor cfpVisitor = new CFPVisitor(false); if (subroutine instanceof JetDeclarationWithBody) { JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine; - CFPVisitor cfpVisitor = new CFPVisitor(false); List valueParameters = declarationWithBody.getValueParameters(); for (JetParameter valueParameter : valueParameters) { valueParameter.accept(cfpVisitor); @@ -81,8 +81,13 @@ public class JetControlFlowProcessor { bodyExpression.accept(cfpVisitor); } } - else { - subroutine.accept(new CFPVisitor(false)); + else if (subroutine instanceof JetProperty) { + JetExpression initializer = ((JetProperty) subroutine).getInitializer(); + if (initializer != null) { + initializer.accept(cfpVisitor); + } + } else { + subroutine.accept(cfpVisitor); } return builder.exitSubroutine(subroutine); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java index a470fcc72ae..06129923e8f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; @@ -74,7 +75,7 @@ public class ControlFlowAnalyzer { private void checkClassOrObject(JetClassOrObject klass) { // A pseudocode of class initialization corresponds to a class - JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, trace); + JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(klass, trace); flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally()); } @@ -86,6 +87,13 @@ public class ControlFlowAnalyzer { assert accessorDescriptor != null; checkFunction(accessor, accessorDescriptor.getReturnType()); } + if (property.getInitializer() != null && propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) { + // check initializer's pseudocode for uninitialized values + // initializers of properties inside classes/objects are checked in 'checkClassOrObject', + // because class/object may have anonymous initialization blocks that affect analysis + JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(property, trace); + flowInformationProvider.markUninitializedVariables(false); + } } private void checkFunction(JetDeclarationWithBody function, final @NotNull JetType expectedReturnType) { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt new file mode 100644 index 00000000000..13f88409d76 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt @@ -0,0 +1,27 @@ +//KT-2960 Perform control flow checks for package property initializers + +package b + +class P { + var x : Int = 0 + private set +} + +val p = P() +var f = { -> p.x = 32 } + +val o = object { + fun run() { + p.x = 4 + + val z : Int + doSmth(z) + } +} + +val g = { -> + val x: Int + doSmth(x) +} + +fun doSmth(i: Int) = i \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 60ceeb7d8b7..70450b56079 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -919,6 +919,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2845.kt"); } + @TestMetadata("kt2960.kt") + public void testKt2960() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt"); + } + @TestMetadata("kt2972.kt") public void testKt2972() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2972.kt");