KT-998: wrong codegen for labeled continue/break
This commit is contained in:
@@ -65,10 +65,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
static class LoopBlockStackElement extends BlockStackElement {
|
||||
final Label continueLabel;
|
||||
final Label breakLabel;
|
||||
public JetSimpleNameExpression targetLabel;
|
||||
|
||||
LoopBlockStackElement(Label breakLabel, Label continueLabel) {
|
||||
LoopBlockStackElement(Label breakLabel, Label continueLabel, JetSimpleNameExpression targetLabel) {
|
||||
this.breakLabel = breakLabel;
|
||||
this.continueLabel = continueLabel;
|
||||
this.targetLabel = targetLabel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +260,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
v.mark(condition);
|
||||
|
||||
Label end = continueLabel != null ? continueLabel : new Label();
|
||||
blockStackElements.push(new LoopBlockStackElement(end, condition));
|
||||
blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression)));
|
||||
|
||||
Label savedContinueLabel = continueLabel;
|
||||
continueLabel = condition;
|
||||
@@ -278,14 +280,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(Type.VOID_TYPE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public StackValue visitDoWhileExpression(JetDoWhileExpression expression, StackValue receiver) {
|
||||
Label condition = new Label();
|
||||
v.mark(condition);
|
||||
|
||||
Label end = new Label();
|
||||
|
||||
blockStackElements.push(new LoopBlockStackElement(end, condition));
|
||||
|
||||
blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression)));
|
||||
|
||||
gen(expression.getBody(), Type.VOID_TYPE);
|
||||
|
||||
@@ -356,7 +359,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
|
||||
Label begin = new Label();
|
||||
blockStackElements.push(new LoopBlockStackElement(end, begin));
|
||||
blockStackElements.push(new LoopBlockStackElement(end, begin, targetLabel(expression)));
|
||||
|
||||
v.mark(begin);
|
||||
v.load(iteratorVar, asmIterType);
|
||||
@@ -426,7 +429,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
Label increment = new Label();
|
||||
v.mark(condition);
|
||||
|
||||
blockStackElements.push(new LoopBlockStackElement(end, increment));
|
||||
blockStackElements.push(new LoopBlockStackElement(end, increment, targetLabel(expression)));
|
||||
|
||||
generateCondition(asmParamType, end);
|
||||
|
||||
@@ -607,9 +610,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else if(stackElement instanceof LoopBlockStackElement) {
|
||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||
Label label = labelElement == null ? loopBlockStackElement.breakLabel : null; // TODO:
|
||||
v.goTo(label);
|
||||
return StackValue.none();
|
||||
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||
v.goTo(loopBlockStackElement.breakLabel);
|
||||
return StackValue.none();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
@@ -632,9 +636,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else if(stackElement instanceof LoopBlockStackElement) {
|
||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||
Label label = labelElement == null ? loopBlockStackElement.continueLabel : null; // TODO:
|
||||
v.goTo(label);
|
||||
return StackValue.none();
|
||||
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||
v.goTo(loopBlockStackElement.continueLabel);
|
||||
return StackValue.none();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
@@ -1960,8 +1965,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
v.invokevirtual("java/lang/StringBuilder", "append", appendDescriptor.getDescriptor());
|
||||
}
|
||||
|
||||
private JetSimpleNameExpression targetLabel(JetExpression expression) {
|
||||
if(expression.getParent() instanceof JetPrefixExpression) {
|
||||
JetPrefixExpression parent = (JetPrefixExpression) expression.getParent();
|
||||
JetSimpleNameExpression operationSign = parent.getOperationReference();
|
||||
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
|
||||
return operationSign;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) {
|
||||
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
|
||||
return genQualified(receiver, expression.getBaseExpression());
|
||||
}
|
||||
|
||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||
final Callable callable = resolveToCallable(op, false);
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
fun findPairless(a : IntArray) : Int {
|
||||
@loop for (i in a.indices) {
|
||||
for (j in a.indices) {
|
||||
if (i != j && a[i] == a[j]) continue@loop
|
||||
}
|
||||
return a[i]
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fun hasDuplicates(a : IntArray) : Boolean {
|
||||
var duplicate = false
|
||||
@loop for (i in a.indices) {
|
||||
for (j in a.indices) {
|
||||
if (i != j && a[i] == a[j]) {
|
||||
duplicate = true
|
||||
break@loop
|
||||
}
|
||||
}
|
||||
return a[i]
|
||||
}
|
||||
return duplicate
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val a = IntArray(5)
|
||||
a[0] = 0
|
||||
a[1] = 0
|
||||
a[2] = 1
|
||||
a[3] = 1
|
||||
a[4] = 5
|
||||
if(findPairless(a) != 5) return "fail"
|
||||
return if(hasDuplicates(a)) "OK" else "fail"
|
||||
|
||||
}
|
||||
@@ -266,4 +266,8 @@ public class ControlStructuresTest extends CodegenTestCase {
|
||||
public void testKt1076() throws Exception {
|
||||
blackBoxFile("regressions/kt1076.kt");
|
||||
}
|
||||
|
||||
public void testKt998() throws Exception {
|
||||
blackBoxFile("regressions/kt998.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user