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 c3a887f4a4f..aaebe73e902 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -69,14 +69,14 @@ public class JetControlFlowProcessor { JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine; List valueParameters = declarationWithBody.getValueParameters(); for (JetParameter valueParameter : valueParameters) { - valueParameter.accept(cfpVisitor); + cfpVisitor.generateInstructions(valueParameter); } JetExpression bodyExpression = declarationWithBody.getBodyExpression(); if (bodyExpression != null) { - bodyExpression.accept(cfpVisitor); + cfpVisitor.generateInstructions(bodyExpression); } } else { - subroutine.accept(cfpVisitor); + cfpVisitor.generateInstructions(subroutine); } return builder.exitSubroutine(subroutine); } @@ -115,18 +115,15 @@ public class JetControlFlowProcessor { throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString()); } }; - private final JetVisitorVoid patternVisitor = new JetVisitorVoid() { - - @Override - public void visitJetElement(@NotNull JetElement element) { - throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString()); - } - }; private CFPVisitor(boolean inCondition) { this.inCondition = inCondition; } + public void generateInstructions(@Nullable JetElement element) { + generateInstructions(element, inCondition); + } + private void generateInstructions(@Nullable JetElement element, boolean inCondition) { if (element == null) return; CFPVisitor visitor; @@ -137,6 +134,22 @@ public class JetControlFlowProcessor { visitor = new CFPVisitor(inCondition); } element.accept(visitor); + checkNothingType(element); + } + + private void checkNothingType(JetElement element) { + if (!(element instanceof JetExpression)) return; + JetExpression expression = JetPsiUtil.deparenthesize((JetExpression) element); + if (expression instanceof JetStatementExpression || expression instanceof JetTryExpression + || expression instanceof JetThrowExpression || expression instanceof JetFinallySection + || expression instanceof JetIfExpression || expression instanceof JetWhenExpression) return; + //noinspection ConstantConditions + if (!trace.get(BindingContext.PROCESSED, expression)) return; + + JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); + if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) { + builder.jumpToError(); + } } @Override @@ -172,12 +185,6 @@ public class JetControlFlowProcessor { @Override public void visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression) { builder.read(expression); - if (trace.get(BindingContext.PROCESSED, expression)) { - JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) { - builder.jumpToError(); - } - } } @Override @@ -662,12 +669,6 @@ public class JetControlFlowProcessor { generateInstructions(selectorExpression, false); } builder.read(expression); - if (trace.get(BindingContext.PROCESSED, expression)) { - JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) { - builder.jumpToError(); - } - } } private void visitCall(JetCallElement call) { @@ -693,12 +694,6 @@ public class JetControlFlowProcessor { generateInstructions(expression.getCalleeExpression(), false); builder.read(expression); - if (trace.get(BindingContext.PROCESSED, expression)) { - JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) { - builder.jumpToError(); - } - } } @Override diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt new file mode 100644 index 00000000000..0cd3fb77b75 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt @@ -0,0 +1,23 @@ +package c + +fun test1() { + val r: Nothing = null!! +} + +fun test2(a: A) { + a + a + bar() +} + +fun test3() { + null!! + bar() +} + +fun throwNPE() = null!! + +class A { + fun plus(a: A): Nothing = throw Exception() +} + +fun bar() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt index 58b1910333a..8fc8a74ae62 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt @@ -1,3 +1,5 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE -UNUSED_PARAMETER +// t is unused due to KT-4233 trait Tr { var v: T } diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt index 36d8d429d53..3f3d866c94d 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE trait Tr { var v: T } diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutPlusAssignDefined.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutPlusAssignDefined.kt index 3d5065d918f..a76e4ea4630 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutPlusAssignDefined.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutPlusAssignDefined.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE trait Tr { var v: T } diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt index 0c282506c9e..1ec5741538e 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt @@ -7,4 +7,5 @@ fun main(args: Array) { } } -fun test(callback: (R) -> Unit):Unit = callback(null!!) +// callback is unused due to KT-4233 +fun test(callback: (R) -> Unit):Unit = callback(null!!) \ 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 cea8f4b17bf..ddc4f976650 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1402,6 +1402,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/checkInnerLocalDeclarations.kt"); } + @TestMetadata("DeadCode.kt") + public void testDeadCode() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt"); + } + @TestMetadata("kt1001.kt") public void testKt1001() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1001.kt");