Merge pull request #108 from udalov/kt2423

KT-2423 Jump after condition check in inner loop is to the wrong label
This commit is contained in:
Alex Tkachman
2012-07-23 09:59:14 -07:00
3 changed files with 55 additions and 20 deletions
@@ -285,21 +285,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Label condition = new Label(); Label condition = new Label();
v.mark(condition); v.mark(condition);
Label end = continueLabel != null ? continueLabel : new Label(); Label end = new Label();
blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression))); blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression)));
Label savedContinueLabel = continueLabel;
continueLabel = condition;
final StackValue conditionValue = gen(expression.getCondition()); final StackValue conditionValue = gen(expression.getCondition());
conditionValue.condJump(end, true, v); conditionValue.condJump(end, true, v);
gen(expression.getBody(), Type.VOID_TYPE); gen(expression.getBody(), Type.VOID_TYPE);
v.goTo(condition); v.goTo(condition);
continueLabel = savedContinueLabel; v.mark(end);
if (end != continueLabel)
v.mark(end);
blockStackElements.pop(); blockStackElements.pop();
@@ -683,14 +678,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) { 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); condition.condJump(end, inverse, v);
gen(expression, Type.VOID_TYPE); gen(expression, Type.VOID_TYPE);
if (continueLabel != end) v.mark(end);
v.mark(end);
return StackValue.none(); return StackValue.none();
} }
@@ -849,8 +843,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.onStack(closure.getClassname().getAsmType()); return StackValue.onStack(closure.getClassname().getAsmType());
} }
private Label continueLabel;
private StackValue generateBlock(List<JetElement> statements) { private StackValue generateBlock(List<JetElement> statements) {
Label blockStart = new Label(); Label blockStart = new Label();
v.mark(blockStart); v.mark(blockStart);
@@ -880,12 +872,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
StackValue answer = StackValue.none(); StackValue answer = StackValue.none();
Label savedContinueLabel = continueLabel;
continueLabel = null;
for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) { for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) {
JetElement statement = statements.get(i); JetElement statement = statements.get(i);
if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) {
continueLabel = savedContinueLabel;
answer = gen(statement); answer = gen(statement);
} }
else { else {
@@ -2709,9 +2698,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
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 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). (or blocks).
*/ */
Label savedContinueLabel = continueLabel;
continueLabel = null;
JetFinallySection finallyBlock = expression.getFinallyBlock(); JetFinallySection finallyBlock = expression.getFinallyBlock();
if (finallyBlock != null) { if (finallyBlock != null) {
blockStackElements.push(new FinallyBlockStackElement(expression)); 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(); blockStackElements.pop();
} }
continueLabel = savedContinueLabel;
return StackValue.onStack(expectedAsmType); return StackValue.onStack(expectedAsmType);
} }
@@ -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"
}
@@ -361,4 +361,9 @@ public class ControlStructuresTest extends CodegenTestCase {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt1688.kt"); blackBoxFile("regressions/kt1688.kt");
} }
public void testKt2423() {
createEnvironmentWithFullJdk();
blackBoxFile("regressions/kt2423.kt");
}
} }