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:
@@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user