RangeContainsLowering: Fix bug in additional condition order for

`until` ranges.
This commit is contained in:
Mark Punzalan
2020-08-07 23:19:44 -07:00
committed by Alexander Udalov
parent 60a2f7d03f
commit ceba9f231d
3 changed files with 37 additions and 1 deletions
@@ -336,7 +336,9 @@ private class Transformer(
).let {
if (additionalNotEmptyCondition != null) {
// Add additional condition, currently used in `until` ranges (see UntilHandler.kt).
context.andand(additionalNotEmptyCondition, it)
// NOTE: The additional condition must be on the RIGHT side of the &&, to guarantee that the expressions for the bounds
// and argument are evaluated as designed. (See big comment above on expressions with side effects and temp variables.)
context.andand(it, additionalNotEmptyCondition)
} else {
it
}
@@ -25,6 +25,8 @@ fun x(i: Int): Int {
return i
}
fun minValue() = Int.MIN_VALUE
fun box(): String {
expectOrder("x(0) in low(1) until high(3)", "LHX") { assertFalse(x(0) in low(1) until high(3)) }
expectOrder("0 in low(1) until high(3)", "LH") { assertFalse(0 in low(1) until high(3)) }
@@ -53,5 +55,20 @@ fun box(): String {
expectOrder("x(2) !in 1 until high(3)", "HX") { assertFalse(x(2) !in 1 until high(3)) }
expectOrder("x(2) !in low(1) until 3", "LX") { assertFalse(x(2) !in low(1) until 3) }
// For IR backend, there is an additional condition for checking the upper bound == MIN_VALUE (empty range).
// These tests ensure all expressions are evaluated and in the correct order.
expectOrder("0 in low(1) until Int.MIN_VALUE", "L") { assertFalse(0 in low(1) until Int.MIN_VALUE) }
expectOrder("0 in low(1) until minValue()", "L") { assertFalse(0 in low(1) until minValue()) }
expectOrder("x(0) in 1 until Int.MIN_VALUE", "X") { assertFalse(x(0) in 1 until Int.MIN_VALUE) }
expectOrder("x(0) in 1 until minValue()", "X") { assertFalse(x(0) in 1 until minValue()) }
expectOrder("x(0) in low(1) until Int.MIN_VALUE", "LX") { assertFalse(x(0) in low(1) until Int.MIN_VALUE) }
expectOrder("x(0) in low(1) until minValue()", "LX") { assertFalse(x(0) in low(1) until minValue()) }
expectOrder("0 !in low(1) until Int.MIN_VALUE", "L") { assertTrue(0 !in low(1) until Int.MIN_VALUE) }
expectOrder("0 !in low(1) until minValue()", "L") { assertTrue(0 !in low(1) until minValue()) }
expectOrder("x(0) !in 1 until Int.MIN_VALUE", "X") { assertTrue(x(0) !in 1 until Int.MIN_VALUE) }
expectOrder("x(0) !in 1 until minValue()", "X") { assertTrue(x(0) !in 1 until minValue()) }
expectOrder("x(0) !in low(1) until Int.MIN_VALUE", "LX") { assertTrue(x(0) !in low(1) until Int.MIN_VALUE) }
expectOrder("x(0) !in low(1) until minValue()", "LX") { assertTrue(x(0) !in low(1) until minValue()) }
return "OK"
}
@@ -25,6 +25,8 @@ fun x(i: Int): Int {
return i
}
fun minValue() = Int.MIN_VALUE
fun box(): String {
expectOrder("x(0) in (low(1) until high(3)).reversed()", "LHX") { assertFalse(x(0) in (low(1) until high(3)).reversed()) }
expectOrder("0 in (low(1) until high(3)).reversed()", "LH") { assertFalse(0 in (low(1) until high(3)).reversed()) }
@@ -53,5 +55,20 @@ fun box(): String {
expectOrder("x(2) !in 1 until high(3)", "HX") { assertFalse(x(2) !in 1 until high(3)) }
expectOrder("x(2) !in low(1) until 3", "LX") { assertFalse(x(2) !in low(1) until 3) }
// For IR backend, there is an additional condition for checking the upper bound == MIN_VALUE (empty range).
// These tests ensure all expressions are evaluated and in the correct order.
expectOrder("0 in (low(1) until Int.MIN_VALUE).reversed()", "L") { assertFalse(0 in (low(1) until Int.MIN_VALUE).reversed()) }
expectOrder("0 in (low(1) until minValue()).reversed()", "L") { assertFalse(0 in (low(1) until minValue()).reversed()) }
expectOrder("x(0) in (1 until Int.MIN_VALUE).reversed()", "X") { assertFalse(x(0) in (1 until Int.MIN_VALUE).reversed()) }
expectOrder("x(0) in (1 until minValue()).reversed()", "X") { assertFalse(x(0) in (1 until minValue()).reversed()) }
expectOrder("x(0) in (low(1) until Int.MIN_VALUE).reversed()", "LX") { assertFalse(x(0) in (low(1) until Int.MIN_VALUE).reversed()) }
expectOrder("x(0) in (low(1) until minValue()).reversed()", "LX") { assertFalse(x(0) in (low(1) until minValue()).reversed()) }
expectOrder("0 !in (low(1) until Int.MIN_VALUE).reversed()", "L") { assertTrue(0 !in (low(1) until Int.MIN_VALUE).reversed()) }
expectOrder("0 !in (low(1) until minValue()).reversed()", "L") { assertTrue(0 !in (low(1) until minValue()).reversed()) }
expectOrder("x(0) !in (1 until Int.MIN_VALUE).reversed()", "X") { assertTrue(x(0) !in (1 until Int.MIN_VALUE).reversed()) }
expectOrder("x(0) !in (1 until minValue()).reversed()", "X") { assertTrue(x(0) !in (1 until minValue()).reversed()) }
expectOrder("x(0) !in (low(1) until Int.MIN_VALUE).reversed()", "LX") { assertTrue(x(0) !in (low(1) until Int.MIN_VALUE).reversed()) }
expectOrder("x(0) !in (low(1) until minValue()).reversed()", "LX") { assertTrue(x(0) !in (low(1) until minValue()).reversed()) }
return "OK"
}