diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4f10ab8aedc..14ac80efc70 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -357,7 +357,7 @@ public class ExpressionCodegen extends JetVisitor implem return genQualified(receiver, expression.getBaseExpression()); } - private static boolean isEmptyExpression(JetElement expr) { + private static boolean isEmptyExpression(@Nullable JetElement expr) { if (expr == null) { return true; } @@ -383,10 +383,6 @@ public class ExpressionCodegen extends JetVisitor implem JetExpression thenExpression = expression.getThen(); JetExpression elseExpression = expression.getElse(); - if (thenExpression == null && elseExpression == null) { - throw new CompilationException("Both brunches of if/else are null", null, expression); - } - if (isEmptyExpression(thenExpression)) { if (isEmptyExpression(elseExpression)) { condition.put(asmType, v); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index a9a1aaccbc2..e54d57f2a42 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -48,7 +48,9 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.util.slicedmap.WritableSlice; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -108,7 +110,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { return getTypeInfoWhenOnlyOneBranchIsPresent( thenBranch, thenScope, thenInfo, elseInfo, contextWithExpectedType, ifExpression, isStatement); } - return JetTypeInfo.create(null, context.dataFlowInfo); + return DataFlowUtils.checkImplicitCast(KotlinBuiltIns.getInstance().getUnitType(), ifExpression, contextWithExpectedType, + isStatement, thenInfo.or(elseInfo)); } if (thenBranch == null) { return getTypeInfoWhenOnlyOneBranchIsPresent( diff --git a/compiler/testData/codegen/box/controlStructures/emptyIf.kt b/compiler/testData/codegen/box/controlStructures/emptyIf.kt new file mode 100644 index 00000000000..0a251a74017 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/emptyIf.kt @@ -0,0 +1,12 @@ +fun box(): String { + if (true); + if (false); + val iftrue = if (true); + val iffalse = if (false); + + var state = 0 + val k = if (state++==1); + if (state != 1) return "Fail: $state" + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt new file mode 100644 index 00000000000..b44d512f18c --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt @@ -0,0 +1,16 @@ +fun foo(x: Unit) = x + +fun test() { + if (false); + if (true); + + val x = if (false); + foo(x) + + val y: Unit = if (false); + foo(y) + + foo({if (1==1);}()) + + return if (true); +} diff --git a/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.kt b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.kt new file mode 100644 index 00000000000..15e3db15c4d --- /dev/null +++ b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.kt @@ -0,0 +1,22 @@ +fun f1(s: String?) { + if (s!! == ""); + s : String +} + +fun f2(s: Number?) { + if (s is Int); + s : Int + if (s as Int == 42); + s : Int +} + +fun f3(s: Number?) { + if (s is Int && s as Int == 42); + s : Int +} + +fun f4(s: Int?) { + var u = if (s!! == 42); + if (u == Unit.VALUE) u = if (s == 239); + return u +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index bb649e37553..ce287155047 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1565,6 +1565,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/controlStructures"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("emptyIf.kt") + public void testEmptyIf() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt"); + } + @TestMetadata("forLoopWithNullableRange.kt") public void testForLoopWithNullableRange() throws Exception { doTest("compiler/testData/diagnostics/tests/controlStructures/forLoopWithNullableRange.kt"); @@ -1757,6 +1762,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/dataFlow/CalleeExpression.kt"); } + @TestMetadata("EmptyIf.kt") + public void testEmptyIf() throws Exception { + doTest("compiler/testData/diagnostics/tests/dataFlow/EmptyIf.kt"); + } + @TestMetadata("IsExpression.kt") public void testIsExpression() throws Exception { doTest("compiler/testData/diagnostics/tests/dataFlow/IsExpression.kt"); @@ -3917,7 +3927,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage public void testContains() throws Exception { doTest("compiler/testData/diagnostics/tests/inline/binaryExpressions/contains.kt"); } - + @TestMetadata("mathOperations.kt") public void testMathOperations() throws Exception { doTest("compiler/testData/diagnostics/tests/inline/binaryExpressions/mathOperations.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 069372d3ce2..9f18cc771f8 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1427,6 +1427,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/controlStructures/doWhileFib.kt"); } + @TestMetadata("emptyIf.kt") + public void testEmptyIf() throws Exception { + doTest("compiler/testData/codegen/box/controlStructures/emptyIf.kt"); + } + @TestMetadata("finallyOnEmptyReturn.kt") public void testFinallyOnEmptyReturn() throws Exception { doTest("compiler/testData/codegen/box/controlStructures/finallyOnEmptyReturn.kt");