KT-13931 generate IntRange#contains with respect to side-effects on argument loading, test added
This commit is contained in:
@@ -3470,38 +3470,35 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
/*
|
||||
* Translates x in a..b (for int and char ranges only)
|
||||
* to a <= x && x >= b same way as javac 1.8.0_91 does.
|
||||
* Translates x in a..b (for int and char ranges only) to a <= x && x <= b
|
||||
*/
|
||||
private void genInIntRange(StackValue leftValue, KtBinaryExpression rangeExpression) {
|
||||
int localVarIndex = myFrameMap.enterTemp(Type.INT_TYPE);
|
||||
|
||||
// Load left bound
|
||||
gen(rangeExpression.getLeft(), Type.INT_TYPE);
|
||||
// Load argument
|
||||
// Load x into local variable to avoid StackValue#put side-effects
|
||||
leftValue.put(Type.INT_TYPE, v);
|
||||
v.store(localVarIndex, Type.INT_TYPE);
|
||||
v.load(localVarIndex, Type.INT_TYPE);
|
||||
|
||||
// If (left > arg) goto L1 (return)
|
||||
// If (x < left) goto L1
|
||||
Label l1 = new Label();
|
||||
v.ificmpgt(l1);
|
||||
|
||||
// Load argument again
|
||||
leftValue.put(Type.INT_TYPE, v);
|
||||
// Load right bound
|
||||
// If (x > right) goto L1
|
||||
v.load(localVarIndex, Type.INT_TYPE);
|
||||
gen(rangeExpression.getRight(), Type.INT_TYPE);
|
||||
// If (x > right) goto L1 (return)
|
||||
v.ificmpgt(l1);
|
||||
|
||||
Label l2 = new Label();
|
||||
// Push 'true'
|
||||
v.iconst(1);
|
||||
// Goto return
|
||||
v.goTo(l2);
|
||||
|
||||
// L1: push 'false'
|
||||
v.mark(l1);
|
||||
v.iconst(0);
|
||||
|
||||
// L2: implicit ireturn
|
||||
v.mark(l2);
|
||||
myFrameMap.leaveTemp(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
private StackValue generateBooleanAnd(KtBinaryExpression expression) {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun box(): String {
|
||||
for (x in 1..10) {
|
||||
assert(x in 1..10)
|
||||
assert(x + 10 !in 1..10)
|
||||
}
|
||||
|
||||
var x = 0
|
||||
assert(0 !in 1..2)
|
||||
|
||||
assert(++x in 1..1)
|
||||
assert(++x !in 1..1)
|
||||
|
||||
assert(sideEffect(x) in 2..3)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
|
||||
var invocationCounter = 0
|
||||
fun sideEffect(x: Int): Int {
|
||||
++invocationCounter
|
||||
assert(invocationCounter == 1)
|
||||
return x
|
||||
}
|
||||
@@ -11128,6 +11128,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inIntRange.kt")
|
||||
public void testInIntRange() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/inIntRange.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt");
|
||||
|
||||
Reference in New Issue
Block a user