From 6eb4cf5aa5c9f0b89d1c891cbf6e78abfb207a87 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 23 Jul 2012 20:09:58 +0400 Subject: [PATCH] KT-2423 Jump after condition check in inner loop is to the wrong label #KT-2423 Fixed --- .../jet/codegen/ExpressionCodegen.java | 24 ++-------- .../testData/codegen/regressions/kt2423.kt | 46 +++++++++++++++++++ .../jet/codegen/ControlStructuresTest.java | 5 ++ 3 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt2423.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index dffe5e8d12e..df283ef452f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -285,21 +285,16 @@ public class ExpressionCodegen extends JetVisitor { Label condition = new Label(); v.mark(condition); - Label end = continueLabel != null ? continueLabel : new Label(); + Label end = new Label(); blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression))); - Label savedContinueLabel = continueLabel; - continueLabel = condition; - final StackValue conditionValue = gen(expression.getCondition()); conditionValue.condJump(end, true, v); gen(expression.getBody(), Type.VOID_TYPE); v.goTo(condition); - continueLabel = savedContinueLabel; - if (end != continueLabel) - v.mark(end); + v.mark(end); blockStackElements.pop(); @@ -683,14 +678,13 @@ public class ExpressionCodegen extends JetVisitor { } private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) { - Label end = continueLabel != null ? continueLabel : new Label(); + Label end = new Label(); condition.condJump(end, inverse, v); gen(expression, Type.VOID_TYPE); - if (continueLabel != end) - v.mark(end); + v.mark(end); return StackValue.none(); } @@ -849,8 +843,6 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(closure.getClassname().getAsmType()); } - private Label continueLabel; - private StackValue generateBlock(List statements) { Label blockStart = new Label(); v.mark(blockStart); @@ -880,12 +872,9 @@ public class ExpressionCodegen extends JetVisitor { } StackValue answer = StackValue.none(); - Label savedContinueLabel = continueLabel; - continueLabel = null; for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) { JetElement statement = statements.get(i); if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { - continueLabel = savedContinueLabel; answer = gen(statement); } else { @@ -2709,9 +2698,6 @@ public class ExpressionCodegen extends JetVisitor { The "returned" value of try expression with no finally is either the last expression in the try block or the last expression in the catch block (or blocks). */ - Label savedContinueLabel = continueLabel; - continueLabel = null; - JetFinallySection finallyBlock = expression.getFinallyBlock(); if (finallyBlock != null) { blockStackElements.push(new FinallyBlockStackElement(expression)); @@ -2771,8 +2757,6 @@ The "returned" value of try expression with no finally is either the last expres blockStackElements.pop(); } - continueLabel = savedContinueLabel; - return StackValue.onStack(expectedAsmType); } diff --git a/compiler/testData/codegen/regressions/kt2423.kt b/compiler/testData/codegen/regressions/kt2423.kt new file mode 100644 index 00000000000..527e44aaa62 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2423.kt @@ -0,0 +1,46 @@ +fun ok1(): Boolean { + val queue = linkedList(1, 2, 3) + while (!queue.isEmpty()) { + queue.poll() + for (y in 1..3) { + if (queue.contains(y)) { + return true + } + } + } + return false +} + +fun ok2(): Boolean { + val queue = linkedList(1, 2, 3) + val array = array(1, 2, 3) + while (!queue.isEmpty()) { + queue.poll() + for (y in array) { + if (queue.contains(y)) { + return true + } + } + } + return false +} + +fun ok3(): Boolean { + val queue = linkedList(1, 2, 3) + while (!queue.isEmpty()) { + queue.poll() + var x = 0 + do { + x++ + if (x == 2) return true + } while (x < 2) + } + return false +} + +fun box(): String { + if (!ok1()) return "Fail #1" + if (!ok2()) return "Fail #2" + if (!ok3()) return "Fail #3" + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index e92b7d005aa..83c2aca2a40 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -361,4 +361,9 @@ public class ControlStructuresTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt1688.kt"); } + + public void testKt2423() { + createEnvironmentWithFullJdk(); + blackBoxFile("regressions/kt2423.kt"); + } }