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 aa28746f47a..6ca902eed6c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -335,29 +335,8 @@ public class JetControlFlowProcessor { JetExpression left = expression.getLeft(); JetExpression right = expression.getRight(); - if (operationType == ANDAND) { - generateInstructions(left, IN_CONDITION); - Label resultLabel = builder.createUnboundLabel(); - builder.jumpOnFalse(resultLabel, expression, builder.getBoundValue(left)); - if (right != null) { - generateInstructions(right, IN_CONDITION); - } - builder.bindLabel(resultLabel); - if (!context.inCondition()) { - predefinedOperation(expression, AND); - } - } - else if (operationType == OROR) { - generateInstructions(left, IN_CONDITION); - Label resultLabel = builder.createUnboundLabel(); - builder.jumpOnTrue(resultLabel, expression, builder.getBoundValue(left)); - if (right != null) { - generateInstructions(right, IN_CONDITION); - } - builder.bindLabel(resultLabel); - if (!context.inCondition()) { - predefinedOperation(expression, OR); - } + if (operationType == ANDAND || operationType == OROR) { + generateBooleanOperation(expression); } else if (operationType == EQ) { visitAssignment(left, getDeferredValue(right), expression); @@ -402,6 +381,27 @@ public class JetControlFlowProcessor { } } + private void generateBooleanOperation(JetBinaryExpression expression) { + IElementType operationType = expression.getOperationReference().getReferencedNameElementType(); + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + + Label resultLabel = builder.createUnboundLabel(); + generateInstructions(left, IN_CONDITION); + if (operationType == ANDAND) { + builder.jumpOnFalse(resultLabel, expression, builder.getBoundValue(left)); + } + else { + builder.jumpOnTrue(resultLabel, expression, builder.getBoundValue(left)); + } + if (right != null) { + generateInstructions(right, IN_CONDITION); + } + builder.bindLabel(resultLabel); + JetControlFlowBuilder.PredefinedOperation operation = operationType == ANDAND ? AND : OR; + builder.predefinedOperation(expression, operation, elementsToValues(Arrays.asList(left, right))); + } + private Function0 getValueAsFunction(final PseudoValue value) { return new Function0() { @Override @@ -421,12 +421,6 @@ public class JetControlFlowProcessor { }; } - private void predefinedOperation(JetBinaryExpression expression, JetControlFlowBuilder.PredefinedOperation operation) { - builder.predefinedOperation( - expression, operation, elementsToValues(Arrays.asList(expression.getLeft(), expression.getRight())) - ); - } - private void generateBothArgumentsAndMark(JetBinaryExpression expression) { JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); if (left != null) { diff --git a/compiler/testData/cfg/expressions/LazyBooleans.instructions b/compiler/testData/cfg/expressions/LazyBooleans.instructions index 3d5bb8a9941..f7e99fd1981 100644 --- a/compiler/testData/cfg/expressions/LazyBooleans.instructions +++ b/compiler/testData/cfg/expressions/LazyBooleans.instructions @@ -40,48 +40,50 @@ L3: r(3) -> mark(if (a && b) 5 else 6) r(a) -> - jf(L4|) NEXT:[jf(L5), r(b) -> ] + jf(L4|) NEXT:[magic(a && b|, ) -> , r(b) -> ] r(b) -> L4: - jf(L5) NEXT:[r(6) -> , r(5) -> ] PREV:[jf(L4|), r(b) -> ] - r(5) -> - jmp(L6) NEXT:[merge(if (a && b) 5 else 6|, ) -> ] + magic(a && b|, ) -> PREV:[jf(L4|), r(b) -> ] + jf(L5|) NEXT:[r(6) -> , r(5) -> ] + r(5) -> + jmp(L6) NEXT:[merge(if (a && b) 5 else 6|, ) -> ] L5: - r(6) -> PREV:[jf(L5)] + r(6) -> PREV:[jf(L5|)] L6: - merge(if (a && b) 5 else 6|, ) -> PREV:[jmp(L6), r(6) -> ] - r(7) -> + merge(if (a && b) 5 else 6|, ) -> PREV:[jmp(L6), r(6) -> ] + r(7) -> mark(if (a || b) 8 else 9) - r(a) -> - jt(L7|) NEXT:[r(b) -> , jf(L8)] - r(b) -> + r(a) -> + jt(L7|) NEXT:[r(b) -> , magic(a || b|, ) -> ] + r(b) -> L7: - jf(L8) NEXT:[r(9) -> , r(8) -> ] PREV:[jt(L7|), r(b) -> ] - r(8) -> - jmp(L9) NEXT:[merge(if (a || b) 8 else 9|, ) -> ] + magic(a || b|, ) -> PREV:[jt(L7|), r(b) -> ] + jf(L8|) NEXT:[r(9) -> , r(8) -> ] + r(8) -> + jmp(L9) NEXT:[merge(if (a || b) 8 else 9|, ) -> ] L8: - r(9) -> PREV:[jf(L8)] + r(9) -> PREV:[jf(L8|)] L9: - merge(if (a || b) 8 else 9|, ) -> PREV:[jmp(L9), r(9) -> ] - r(10) -> + merge(if (a || b) 8 else 9|, ) -> PREV:[jmp(L9), r(9) -> ] + r(10) -> mark(if (a) 11) - r(a) -> - jf(L10|) NEXT:[read (Unit), r(11) -> ] - r(11) -> - jmp(L11) NEXT:[r(12) -> ] + r(a) -> + jf(L10|) NEXT:[read (Unit), r(11) -> ] + r(11) -> + jmp(L11) NEXT:[r(12) -> ] L10: - read (Unit) PREV:[jf(L10|)] + read (Unit) PREV:[jf(L10|)] L11: - r(12) -> PREV:[jmp(L11), read (Unit)] + r(12) -> PREV:[jmp(L11), read (Unit)] mark(if (a) else 13) - r(a) -> - jf(L12|) NEXT:[r(13) -> , read (Unit)] + r(a) -> + jf(L12|) NEXT:[r(13) -> , read (Unit)] read (Unit) - jmp(L13) NEXT:[r(14) -> ] + jmp(L13) NEXT:[r(14) -> ] L12: - r(13) -> PREV:[jf(L12|)] + r(13) -> PREV:[jf(L12|)] L13: - r(14) -> PREV:[jmp(L13), r(13) -> ] + r(14) -> PREV:[jmp(L13), r(13) -> ] L1: 1 NEXT:[] error: diff --git a/compiler/testData/cfg/expressions/LazyBooleans.values b/compiler/testData/cfg/expressions/LazyBooleans.values index 875bf5a3649..fcd696e1030 100644 --- a/compiler/testData/cfg/expressions/LazyBooleans.values +++ b/compiler/testData/cfg/expressions/LazyBooleans.values @@ -17,7 +17,7 @@ fun lazyBooleans(a : Boolean, b : Boolean) : Unit { 14 } --------------------- -a NEW() +a NEW() 1 NEW() { 1 } COPY 2 NEW() @@ -26,23 +26,25 @@ if (a) { 1 } else { 2 } 3 NEW() a NEW() b NEW() -5 NEW() -6 NEW() -if (a && b) 5 else 6 NEW(, ) -7 NEW() -a NEW() -b NEW() -8 NEW() -9 NEW() -if (a || b) 8 else 9 NEW(, ) -10 NEW() -a NEW() -11 NEW() -if (a) 11 COPY -12 NEW() -a NEW() -13 NEW() -if (a) else 13 COPY -14 NEW() -{ if (a) { 1 } else { 2 } 3 if (a && b) 5 else 6 7 if (a || b) 8 else 9 10 if (a) 11 12 if (a) else 13 14 } COPY +a && b NEW(, ) +5 NEW() +6 NEW() +if (a && b) 5 else 6 NEW(, ) +7 NEW() +a NEW() +b NEW() +a || b NEW(, ) +8 NEW() +9 NEW() +if (a || b) 8 else 9 NEW(, ) +10 NEW() +a NEW() +11 NEW() +if (a) 11 COPY +12 NEW() +a NEW() +13 NEW() +if (a) else 13 COPY +14 NEW() +{ if (a) { 1 } else { 2 } 3 if (a && b) 5 else 6 7 if (a || b) 8 else 9 10 if (a) 11 12 if (a) else 13 14 } COPY ===================== diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt index 627bbd0fd81..d3019a67a22 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt @@ -138,7 +138,7 @@ fun tf() : Int { } fun failtest(a : Int) : Int { - if (fail() || true) { + if (fail() || true) { } return 1 diff --git a/idea/testData/checker/UnreachableCode.kt b/idea/testData/checker/UnreachableCode.kt index 70599cadac0..1f1c1c5245b 100644 --- a/idea/testData/checker/UnreachableCode.kt +++ b/idea/testData/checker/UnreachableCode.kt @@ -136,7 +136,7 @@ fun tf() : Int { } fun failtest(a : Int) : Int { - if (fail() || true) { + if (fail() || true) { } return 1