IR: add an emptiness check to all unsigned until loops
Unlike signed integers, a larger unsigned type does not mean a lower minimum value, so `x - 1` can overflow even if `x` is casted to a larger type. #KT-42186 Fixed
This commit is contained in:
@@ -4,27 +4,89 @@
|
||||
|
||||
|
||||
val MinI = Int.MIN_VALUE
|
||||
val MinB = Byte.MIN_VALUE
|
||||
val MinS = Short.MIN_VALUE
|
||||
val MinL = Long.MIN_VALUE
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
val range1 = 0..MinI step 3
|
||||
val range1 = 0.toByte()..MinB step 3
|
||||
for (i in range1) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list1"
|
||||
return "Wrong elements for 0.toByte()..MinB step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
val range2 = 0L..MinL step 3
|
||||
val list2 = ArrayList<Int>()
|
||||
val range2 = 0.toShort()..MinS step 3
|
||||
for (i in range2) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list2"
|
||||
if (list2 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toShort()..MinS step 3: $list2"
|
||||
}
|
||||
|
||||
val list3 = ArrayList<Int>()
|
||||
val range3 = 0..MinI step 3
|
||||
for (i in range3) {
|
||||
list3.add(i)
|
||||
if (list3.size > 23) break
|
||||
}
|
||||
if (list3 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list3"
|
||||
}
|
||||
|
||||
val list4 = ArrayList<Long>()
|
||||
val range4 = 0L..MinL step 3
|
||||
for (i in range4) {
|
||||
list4.add(i)
|
||||
if (list4.size > 23) break
|
||||
}
|
||||
if (list4 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list4"
|
||||
}
|
||||
|
||||
val list5 = ArrayList<Int>()
|
||||
val range5 = 0.toByte() until MinB step 3
|
||||
for (i in range5) {
|
||||
list5.add(i)
|
||||
if (list5.size > 23) break
|
||||
}
|
||||
if (list5 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toByte() until MinB step 3: $list5"
|
||||
}
|
||||
|
||||
val list6 = ArrayList<Int>()
|
||||
val range6 = 0.toShort() until MinS step 3
|
||||
for (i in range6) {
|
||||
list6.add(i)
|
||||
if (list6.size > 23) break
|
||||
}
|
||||
if (list6 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toShort() until MinS step 3: $list6"
|
||||
}
|
||||
|
||||
val list7 = ArrayList<Int>()
|
||||
val range7 = 0 until MinI step 3
|
||||
for (i in range7) {
|
||||
list7.add(i)
|
||||
if (list7.size > 23) break
|
||||
}
|
||||
if (list7 != listOf<Int>()) {
|
||||
return "Wrong elements for 0 until MinI step 3: $list7"
|
||||
}
|
||||
|
||||
val list8 = ArrayList<Long>()
|
||||
val range8 = 0L until MinL step 3
|
||||
for (i in range8) {
|
||||
list8.add(i)
|
||||
if (list8.size > 23) break
|
||||
}
|
||||
if (list8 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L until MinL step 3: $list8"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -4,25 +4,81 @@
|
||||
|
||||
|
||||
val MinI = Int.MIN_VALUE
|
||||
val MinB = Byte.MIN_VALUE
|
||||
val MinS = Short.MIN_VALUE
|
||||
val MinL = Long.MIN_VALUE
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
for (i in 0..MinI step 3) {
|
||||
for (i in 0.toByte()..MinB step 3) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list1"
|
||||
return "Wrong elements for 0.toByte()..MinB step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
for (i in 0L..MinL step 3) {
|
||||
val list2 = ArrayList<Int>()
|
||||
for (i in 0.toShort()..MinS step 3) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list2"
|
||||
if (list2 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toShort()..MinS step 3: $list2"
|
||||
}
|
||||
|
||||
val list3 = ArrayList<Int>()
|
||||
for (i in 0..MinI step 3) {
|
||||
list3.add(i)
|
||||
if (list3.size > 23) break
|
||||
}
|
||||
if (list3 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list3"
|
||||
}
|
||||
|
||||
val list4 = ArrayList<Long>()
|
||||
for (i in 0L..MinL step 3) {
|
||||
list4.add(i)
|
||||
if (list4.size > 23) break
|
||||
}
|
||||
if (list4 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list4"
|
||||
}
|
||||
|
||||
val list5 = ArrayList<Int>()
|
||||
for (i in 0.toByte() until MinB step 3) {
|
||||
list5.add(i)
|
||||
if (list5.size > 23) break
|
||||
}
|
||||
if (list5 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toByte() until MinB step 3: $list5"
|
||||
}
|
||||
|
||||
val list6 = ArrayList<Int>()
|
||||
for (i in 0.toShort() until MinS step 3) {
|
||||
list6.add(i)
|
||||
if (list6.size > 23) break
|
||||
}
|
||||
if (list6 != listOf<Int>()) {
|
||||
return "Wrong elements for 0.toShort() until MinS step 3: $list6"
|
||||
}
|
||||
|
||||
val list7 = ArrayList<Int>()
|
||||
for (i in 0 until MinI step 3) {
|
||||
list7.add(i)
|
||||
if (list7.size > 23) break
|
||||
}
|
||||
if (list7 != listOf<Int>()) {
|
||||
return "Wrong elements for 0 until MinI step 3: $list7"
|
||||
}
|
||||
|
||||
val list8 = ArrayList<Long>()
|
||||
for (i in 0L until MinL step 3) {
|
||||
list8.add(i)
|
||||
if (list8.size > 23) break
|
||||
}
|
||||
if (list8 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L until MinL step 3: $list8"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
|
||||
+68
-6
@@ -4,27 +4,89 @@
|
||||
|
||||
|
||||
val MinUI = UInt.MIN_VALUE
|
||||
val MinUB = UByte.MIN_VALUE
|
||||
val MinUS = UShort.MIN_VALUE
|
||||
val MinUL = ULong.MIN_VALUE
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<UInt>()
|
||||
val range1 = 1u..MinUI step 3
|
||||
val range1 = 1u.toUByte()..MinUB step 3
|
||||
for (i in range1) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u..MinUI step 3: $list1"
|
||||
return "Wrong elements for 1u.toUByte()..MinUB step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<ULong>()
|
||||
val range2 = 1uL..MinUL step 3
|
||||
val list2 = ArrayList<UInt>()
|
||||
val range2 = 1u.toUShort()..MinUS step 3
|
||||
for (i in range2) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL..MinUL step 3: $list2"
|
||||
if (list2 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUShort()..MinUS step 3: $list2"
|
||||
}
|
||||
|
||||
val list3 = ArrayList<UInt>()
|
||||
val range3 = 1u..MinUI step 3
|
||||
for (i in range3) {
|
||||
list3.add(i)
|
||||
if (list3.size > 23) break
|
||||
}
|
||||
if (list3 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u..MinUI step 3: $list3"
|
||||
}
|
||||
|
||||
val list4 = ArrayList<ULong>()
|
||||
val range4 = 1uL..MinUL step 3
|
||||
for (i in range4) {
|
||||
list4.add(i)
|
||||
if (list4.size > 23) break
|
||||
}
|
||||
if (list4 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL..MinUL step 3: $list4"
|
||||
}
|
||||
|
||||
val list5 = ArrayList<UInt>()
|
||||
val range5 = 1u.toUByte() until MinUB step 3
|
||||
for (i in range5) {
|
||||
list5.add(i)
|
||||
if (list5.size > 23) break
|
||||
}
|
||||
if (list5 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUByte() until MinUB step 3: $list5"
|
||||
}
|
||||
|
||||
val list6 = ArrayList<UInt>()
|
||||
val range6 = 1u.toUShort() until MinUS step 3
|
||||
for (i in range6) {
|
||||
list6.add(i)
|
||||
if (list6.size > 23) break
|
||||
}
|
||||
if (list6 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUShort() until MinUS step 3: $list6"
|
||||
}
|
||||
|
||||
val list7 = ArrayList<UInt>()
|
||||
val range7 = 1u until MinUI step 3
|
||||
for (i in range7) {
|
||||
list7.add(i)
|
||||
if (list7.size > 23) break
|
||||
}
|
||||
if (list7 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u until MinUI step 3: $list7"
|
||||
}
|
||||
|
||||
val list8 = ArrayList<ULong>()
|
||||
val range8 = 1uL until MinUL step 3
|
||||
for (i in range8) {
|
||||
list8.add(i)
|
||||
if (list8.size > 23) break
|
||||
}
|
||||
if (list8 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL until MinUL step 3: $list8"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
|
||||
+62
-6
@@ -4,25 +4,81 @@
|
||||
|
||||
|
||||
val MinUI = UInt.MIN_VALUE
|
||||
val MinUB = UByte.MIN_VALUE
|
||||
val MinUS = UShort.MIN_VALUE
|
||||
val MinUL = ULong.MIN_VALUE
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<UInt>()
|
||||
for (i in 1u..MinUI step 3) {
|
||||
for (i in 1u.toUByte()..MinUB step 3) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u..MinUI step 3: $list1"
|
||||
return "Wrong elements for 1u.toUByte()..MinUB step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<ULong>()
|
||||
for (i in 1uL..MinUL step 3) {
|
||||
val list2 = ArrayList<UInt>()
|
||||
for (i in 1u.toUShort()..MinUS step 3) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL..MinUL step 3: $list2"
|
||||
if (list2 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUShort()..MinUS step 3: $list2"
|
||||
}
|
||||
|
||||
val list3 = ArrayList<UInt>()
|
||||
for (i in 1u..MinUI step 3) {
|
||||
list3.add(i)
|
||||
if (list3.size > 23) break
|
||||
}
|
||||
if (list3 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u..MinUI step 3: $list3"
|
||||
}
|
||||
|
||||
val list4 = ArrayList<ULong>()
|
||||
for (i in 1uL..MinUL step 3) {
|
||||
list4.add(i)
|
||||
if (list4.size > 23) break
|
||||
}
|
||||
if (list4 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL..MinUL step 3: $list4"
|
||||
}
|
||||
|
||||
val list5 = ArrayList<UInt>()
|
||||
for (i in 1u.toUByte() until MinUB step 3) {
|
||||
list5.add(i)
|
||||
if (list5.size > 23) break
|
||||
}
|
||||
if (list5 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUByte() until MinUB step 3: $list5"
|
||||
}
|
||||
|
||||
val list6 = ArrayList<UInt>()
|
||||
for (i in 1u.toUShort() until MinUS step 3) {
|
||||
list6.add(i)
|
||||
if (list6.size > 23) break
|
||||
}
|
||||
if (list6 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u.toUShort() until MinUS step 3: $list6"
|
||||
}
|
||||
|
||||
val list7 = ArrayList<UInt>()
|
||||
for (i in 1u until MinUI step 3) {
|
||||
list7.add(i)
|
||||
if (list7.size > 23) break
|
||||
}
|
||||
if (list7 != listOf<UInt>()) {
|
||||
return "Wrong elements for 1u until MinUI step 3: $list7"
|
||||
}
|
||||
|
||||
val list8 = ArrayList<ULong>()
|
||||
for (i in 1uL until MinUL step 3) {
|
||||
list8.add(i)
|
||||
if (list8.size > 23) break
|
||||
}
|
||||
if (list8 != listOf<ULong>()) {
|
||||
return "Wrong elements for 1uL until MinUL step 3: $list8"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
fun testUByteUntilUByte(a: UByte, b: UByte): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum += i.toInt()
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testUShortUntilUShort(a: UShort, b: UShort): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum += i.toInt()
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// However, this check is not needed when the upper bound is smaller than the range element type.
|
||||
// Here are the available `until` extension functions with mixed bounds that return UIntRange:
|
||||
//
|
||||
// infix fun UByte.until(to: UByte): UIntRange // NO bound check needed
|
||||
// infix fun UShort.until(to: UShort): UIntRange // NO bound check needed
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IFGT
|
||||
// 2 IFLE
|
||||
// 4 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
Reference in New Issue
Block a user