Support unsigned range and progression values in range intrinsics
This commit is contained in:
@@ -36,47 +36,46 @@ private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isPrimitiveRange(rangeType: KotlinType) =
|
fun isPrimitiveRange(rangeType: KotlinType) =
|
||||||
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
|
isClassTypeWithFqn(rangeType, PRIMITIVE_RANGE_FQNS)
|
||||||
|
|
||||||
|
fun isUnsignedRange(rangeType: KotlinType): Boolean =
|
||||||
|
isClassTypeWithFqn(rangeType, UNSIGNED_RANGE_FQNS)
|
||||||
|
|
||||||
fun isPrimitiveProgression(rangeType: KotlinType) =
|
fun isPrimitiveProgression(rangeType: KotlinType) =
|
||||||
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
|
isClassTypeWithFqn(rangeType, PRIMITIVE_PROGRESSION_FQNS)
|
||||||
|
|
||||||
fun getPrimitiveRangeElementType(rangeType: KotlinType): PrimitiveType? =
|
fun isUnsignedProgression(rangeType: KotlinType) =
|
||||||
getPrimitiveRangeOrProgressionElementType(
|
isClassTypeWithFqn(rangeType, UNSIGNED_PROGRESSION_FQNS)
|
||||||
rangeType,
|
|
||||||
RANGE_TO_ELEMENT_TYPE
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
|
private fun isClassTypeWithFqn(kotlinType: KotlinType, fqns: Set<String>): Boolean {
|
||||||
getPrimitiveRangeOrProgressionElementType(
|
val declarationDescriptor = kotlinType.constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
||||||
rangeType,
|
val fqName = DescriptorUtils.getFqName(declarationDescriptor).takeIf { it.isSafe } ?: return false
|
||||||
PROGRESSION_TO_ELEMENT_TYPE
|
return fqName.asString() in fqns
|
||||||
)
|
|
||||||
|
|
||||||
private fun getPrimitiveRangeOrProgressionElementType(
|
|
||||||
rangeOrProgression: KotlinType,
|
|
||||||
map: Map<FqName, PrimitiveType>
|
|
||||||
): PrimitiveType? {
|
|
||||||
val declarationDescriptor = rangeOrProgression.constructor.declarationDescriptor ?: return null
|
|
||||||
val fqName = DescriptorUtils.getFqName(declarationDescriptor).takeIf { it.isSafe } ?: return null
|
|
||||||
return map[fqName.toSafe()]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val CHAR_RANGE_FQN = "kotlin.ranges.CharRange"
|
private const val CHAR_RANGE_FQN = "kotlin.ranges.CharRange"
|
||||||
private const val INT_RANGE_FQN = "kotlin.ranges.IntRange"
|
private const val INT_RANGE_FQN = "kotlin.ranges.IntRange"
|
||||||
private const val LONG_RANGE_FQN = "kotlin.ranges.LongRange"
|
private const val LONG_RANGE_FQN = "kotlin.ranges.LongRange"
|
||||||
|
private val PRIMITIVE_RANGE_FQNS = setOf(CHAR_RANGE_FQN, INT_RANGE_FQN, LONG_RANGE_FQN)
|
||||||
|
|
||||||
private const val CHAR_PROGRESSION_FQN = "kotlin.ranges.CharProgression"
|
private const val CHAR_PROGRESSION_FQN = "kotlin.ranges.CharProgression"
|
||||||
private const val INT_PROGRESSION_FQN = "kotlin.ranges.IntProgression"
|
private const val INT_PROGRESSION_FQN = "kotlin.ranges.IntProgression"
|
||||||
private const val LONG_PROGRESSION_FQN = "kotlin.ranges.LongProgression"
|
private const val LONG_PROGRESSION_FQN = "kotlin.ranges.LongProgression"
|
||||||
|
private val PRIMITIVE_PROGRESSION_FQNS = setOf(CHAR_PROGRESSION_FQN, INT_PROGRESSION_FQN, LONG_PROGRESSION_FQN)
|
||||||
|
|
||||||
private const val CLOSED_FLOAT_RANGE_FQN = "kotlin.ranges.ClosedFloatRange"
|
private const val CLOSED_FLOAT_RANGE_FQN = "kotlin.ranges.ClosedFloatRange"
|
||||||
private const val CLOSED_DOUBLE_RANGE_FQN = "kotlin.ranges.ClosedDoubleRange"
|
private const val CLOSED_DOUBLE_RANGE_FQN = "kotlin.ranges.ClosedDoubleRange"
|
||||||
private const val CLOSED_RANGE_FQN = "kotlin.ranges.ClosedRange"
|
private const val CLOSED_RANGE_FQN = "kotlin.ranges.ClosedRange"
|
||||||
private const val CLOSED_FLOATING_POINT_RANGE_FQN = "kotlin.ranges.ClosedFloatingPointRange"
|
private const val CLOSED_FLOATING_POINT_RANGE_FQN = "kotlin.ranges.ClosedFloatingPointRange"
|
||||||
private const val COMPARABLE_RANGE_FQN = "kotlin.ranges.ComparableRange"
|
private const val COMPARABLE_RANGE_FQN = "kotlin.ranges.ComparableRange"
|
||||||
|
|
||||||
private const val UINT_RANGE_FQN = "kotlin.ranges.UIntRange"
|
private const val UINT_RANGE_FQN = "kotlin.ranges.UIntRange"
|
||||||
private const val ULONG_RANGE_FQN = "kotlin.ranges.ULongRange"
|
private const val ULONG_RANGE_FQN = "kotlin.ranges.ULongRange"
|
||||||
|
private val UNSIGNED_RANGE_FQNS = setOf(UINT_RANGE_FQN, ULONG_RANGE_FQN)
|
||||||
|
|
||||||
private const val UINT_PROGRESSION_FQN = "kotlin.ranges.UIntProgression"
|
private const val UINT_PROGRESSION_FQN = "kotlin.ranges.UIntProgression"
|
||||||
private const val ULONG_PROGRESSION_FQN = "kotlin.ranges.ULongProgression"
|
private const val ULONG_PROGRESSION_FQN = "kotlin.ranges.ULongProgression"
|
||||||
|
private val UNSIGNED_PROGRESSION_FQNS = setOf(UINT_PROGRESSION_FQN, ULONG_PROGRESSION_FQN)
|
||||||
|
|
||||||
fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
|
fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
|
||||||
val rangeClassDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
val rangeClassDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ fun ExpressionCodegen.createRangeValueForExpression(rangeExpression: KtExpressio
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
isPrimitiveRange(rangeType) ->
|
isPrimitiveRange(rangeType) || isUnsignedRange(rangeType) ->
|
||||||
PrimitiveRangeRangeValue(rangeExpression)
|
PrimitiveRangeRangeValue(rangeExpression)
|
||||||
isPrimitiveProgression(rangeType) ->
|
isPrimitiveProgression(rangeType) || isUnsignedProgression(rangeType) ->
|
||||||
PrimitiveProgressionRangeValue(rangeExpression)
|
PrimitiveProgressionRangeValue(rangeExpression)
|
||||||
isSubtypeOfString(rangeType, builtIns) && isCharSequenceIteratorCall(loopRangeIteratorResolvedCall) ->
|
isSubtypeOfString(rangeType, builtIns) && isCharSequenceIteratorCall(loopRangeIteratorResolvedCall) ->
|
||||||
CharSequenceRangeValue(true, AsmTypes.JAVA_STRING_TYPE)
|
CharSequenceRangeValue(true, AsmTypes.JAVA_STRING_TYPE)
|
||||||
@@ -75,6 +75,7 @@ fun ExpressionCodegen.createRangeValueForExpression(rangeExpression: KtExpressio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun isLocalVarReference(rangeExpression: KtExpression, bindingContext: BindingContext): Boolean {
|
fun isLocalVarReference(rangeExpression: KtExpression, bindingContext: BindingContext): Boolean {
|
||||||
if (rangeExpression !is KtSimpleNameExpression) return false
|
if (rangeExpression !is KtSimpleNameExpression) return false
|
||||||
val resultingDescriptor = rangeExpression.getResolvedCall(bindingContext)?.resultingDescriptor ?: return false
|
val resultingDescriptor = rangeExpression.getResolvedCall(bindingContext)?.resultingDescriptor ?: return false
|
||||||
|
|||||||
+4
@@ -35,6 +35,10 @@ interface ComparisonGenerator {
|
|||||||
fun jumpIfLess(v: InstructionAdapter, label: Label)
|
fun jumpIfLess(v: InstructionAdapter, label: Label)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SignedIntegerComparisonGenerator : ComparisonGenerator {
|
||||||
|
fun jumpIfLessThanZero(v: InstructionAdapter, label: Label)
|
||||||
|
}
|
||||||
|
|
||||||
fun getComparisonGeneratorForKotlinType(kotlinType: KotlinType): ComparisonGenerator =
|
fun getComparisonGeneratorForKotlinType(kotlinType: KotlinType): ComparisonGenerator =
|
||||||
when {
|
when {
|
||||||
KotlinBuiltIns.isChar(kotlinType) ->
|
KotlinBuiltIns.isChar(kotlinType) ->
|
||||||
|
|||||||
+5
-1
@@ -20,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.Label
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
class IntegerComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
class IntegerComparisonGenerator(override val comparedType: Type) : SignedIntegerComparisonGenerator {
|
||||||
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
||||||
v.ificmpge(label)
|
v.ificmpge(label)
|
||||||
}
|
}
|
||||||
@@ -36,6 +36,10 @@ class IntegerComparisonGenerator(override val comparedType: Type) : ComparisonGe
|
|||||||
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
|
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
|
||||||
v.ificmplt(label)
|
v.ificmplt(label)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun jumpIfLessThanZero(v: InstructionAdapter, label: Label) {
|
||||||
|
v.iflt(label)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val IntComparisonGenerator = IntegerComparisonGenerator(Type.INT_TYPE)
|
val IntComparisonGenerator = IntegerComparisonGenerator(Type.INT_TYPE)
|
||||||
|
|||||||
+7
-1
@@ -20,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.Label
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
object LongComparisonGenerator : ComparisonGenerator {
|
object LongComparisonGenerator : SignedIntegerComparisonGenerator {
|
||||||
override val comparedType: Type = Type.LONG_TYPE
|
override val comparedType: Type = Type.LONG_TYPE
|
||||||
|
|
||||||
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
||||||
@@ -42,4 +42,10 @@ object LongComparisonGenerator : ComparisonGenerator {
|
|||||||
v.lcmp()
|
v.lcmp()
|
||||||
v.iflt(label)
|
v.iflt(label)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun jumpIfLessThanZero(v: InstructionAdapter, label: Label) {
|
||||||
|
v.lconst(0L)
|
||||||
|
v.lcmp()
|
||||||
|
v.iflt(label)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+29
-35
@@ -18,6 +18,9 @@ package org.jetbrains.kotlin.codegen.range.forLoop
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
|
import org.jetbrains.kotlin.codegen.range.comparison.SignedIntegerComparisonGenerator
|
||||||
|
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||||
|
import org.jetbrains.kotlin.codegen.range.getRangeOrProgressionElementType
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
@@ -25,22 +28,34 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) :
|
abstract class AbstractForInProgressionLoopGenerator(
|
||||||
AbstractForInProgressionOrRangeLoopGenerator(codegen, forExpression) {
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression
|
||||||
|
) : AbstractForInProgressionOrRangeLoopGenerator(codegen, forExpression) {
|
||||||
|
|
||||||
protected var incrementVar: Int = -1
|
protected var incrementVar: Int = -1
|
||||||
protected val asmLoopRangeType: Type
|
protected val asmLoopRangeType: Type
|
||||||
protected val kotlinLoopRangeType: KotlinType
|
protected val rangeKotlinType = bindingContext.getType(forExpression.loopRange!!)!!
|
||||||
|
private val rangeElementKotlinType = getRangeOrProgressionElementType(rangeKotlinType)
|
||||||
|
?: throw AssertionError("Unexpected loop range type: $rangeKotlinType")
|
||||||
|
private val incrementKotlinType: KotlinType
|
||||||
protected val incrementType: Type
|
protected val incrementType: Type
|
||||||
|
|
||||||
init {
|
init {
|
||||||
kotlinLoopRangeType = bindingContext.getType(forExpression.loopRange!!)!!
|
asmLoopRangeType = codegen.asmType(rangeKotlinType)
|
||||||
asmLoopRangeType = codegen.asmType(kotlinLoopRangeType)
|
|
||||||
|
|
||||||
val incrementProp = kotlinLoopRangeType.memberScope.getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND)
|
val incrementProp = rangeKotlinType.memberScope.getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND)
|
||||||
assert(incrementProp.size == 1) { kotlinLoopRangeType.toString() + " " + incrementProp.size }
|
assert(incrementProp.size == 1) { rangeKotlinType.toString() + " " + incrementProp.size }
|
||||||
incrementType = codegen.asmType(incrementProp.iterator().next().type)
|
incrementKotlinType = incrementProp.single().type
|
||||||
|
incrementType = codegen.asmType(incrementKotlinType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val incrementComparisonGenerator =
|
||||||
|
getComparisonGeneratorForKotlinType(incrementKotlinType) as? SignedIntegerComparisonGenerator
|
||||||
|
?: throw AssertionError("Unexpected increment type: $incrementKotlinType")
|
||||||
|
|
||||||
|
private val elementComparisonGenerator = getComparisonGeneratorForKotlinType(rangeElementKotlinType)
|
||||||
|
|
||||||
override fun beforeLoop() {
|
override fun beforeLoop() {
|
||||||
super.beforeLoop()
|
super.beforeLoop()
|
||||||
|
|
||||||
@@ -59,33 +74,12 @@ abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen,
|
|||||||
val negativeIncrement = Label()
|
val negativeIncrement = Label()
|
||||||
val afterIf = Label()
|
val afterIf = Label()
|
||||||
|
|
||||||
if (asmElementType.sort == Type.LONG) {
|
incrementComparisonGenerator.jumpIfLessThanZero(v, negativeIncrement)
|
||||||
v.lconst(0L)
|
elementComparisonGenerator.jumpIfGreater(v, loopExit)
|
||||||
v.lcmp()
|
v.goTo(afterIf)
|
||||||
v.ifle(negativeIncrement) // if increment < 0, jump
|
v.mark(negativeIncrement)
|
||||||
|
elementComparisonGenerator.jumpIfLess(v, loopExit)
|
||||||
// increment > 0
|
v.mark(afterIf)
|
||||||
v.lcmp()
|
|
||||||
v.ifgt(loopExit)
|
|
||||||
v.goTo(afterIf)
|
|
||||||
|
|
||||||
// increment < 0
|
|
||||||
v.mark(negativeIncrement)
|
|
||||||
v.lcmp()
|
|
||||||
v.iflt(loopExit)
|
|
||||||
v.mark(afterIf)
|
|
||||||
} else {
|
|
||||||
v.ifle(negativeIncrement) // if increment < 0, jump
|
|
||||||
|
|
||||||
// increment > 0
|
|
||||||
v.ificmpgt(loopExit)
|
|
||||||
v.goTo(afterIf)
|
|
||||||
|
|
||||||
// increment < 0
|
|
||||||
v.mark(negativeIncrement)
|
|
||||||
v.ificmplt(loopExit)
|
|
||||||
v.mark(afterIf)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun assignToLoopParameter() {}
|
override fun assignToLoopParameter() {}
|
||||||
|
|||||||
+2
-1
@@ -25,8 +25,9 @@ class ForInProgressionExpressionLoopGenerator(
|
|||||||
forExpression: KtForExpression,
|
forExpression: KtForExpression,
|
||||||
private val rangeExpression: KtExpression
|
private val rangeExpression: KtExpression
|
||||||
) : AbstractForInProgressionLoopGenerator(codegen, forExpression) {
|
) : AbstractForInProgressionLoopGenerator(codegen, forExpression) {
|
||||||
|
|
||||||
override fun storeProgressionParametersToLocalVars() {
|
override fun storeProgressionParametersToLocalVars() {
|
||||||
codegen.gen(rangeExpression, asmLoopRangeType, kotlinLoopRangeType)
|
codegen.gen(rangeExpression, asmLoopRangeType, rangeKotlinType)
|
||||||
v.dup()
|
v.dup()
|
||||||
v.dup()
|
v.dup()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
const val MaxUI = UInt.MAX_VALUE
|
||||||
|
const val MinUI = UInt.MIN_VALUE
|
||||||
|
|
||||||
|
const val MaxUL = ULong.MAX_VALUE
|
||||||
|
const val MinUL = ULong.MIN_VALUE
|
||||||
|
|
||||||
|
val M = MaxUI.toULong()
|
||||||
|
|
||||||
|
val p1 = 6u downTo 1u
|
||||||
|
fun testSimpleUIntLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p1) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 654321) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p2 = 1u downTo 6u
|
||||||
|
fun testEmptyUIntLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p2) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p3 = 6UL downTo 1UL
|
||||||
|
fun testSimpleULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p3) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 654321) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p4 = 1UL downTo 6UL
|
||||||
|
fun testEmptyULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p4) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p5 = M + 6UL downTo M + 1UL
|
||||||
|
fun testULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p5) {
|
||||||
|
s = s*10 + (i-M).toInt()
|
||||||
|
}
|
||||||
|
if (s != 654321) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p6 = M + 1UL downTo M + 6UL
|
||||||
|
fun testEmptyULongLoop2() {
|
||||||
|
var s = 0
|
||||||
|
for (i in p6) {
|
||||||
|
s = s*10 + (i-M).toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val p7 = MinUI downTo MaxUI
|
||||||
|
fun testMaxUIdownToMinUI() {
|
||||||
|
val xs = ArrayList<UInt>()
|
||||||
|
for (i in p7) {
|
||||||
|
xs.add(i)
|
||||||
|
if (xs.size > 23) break
|
||||||
|
}
|
||||||
|
if (xs.size > 0) {
|
||||||
|
throw AssertionError("Wrong elements for MaxUI..MinUI: $xs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val p8 = MinUL downTo MaxUL
|
||||||
|
fun testMaxULdownToMinUL() {
|
||||||
|
val xs = ArrayList<ULong>()
|
||||||
|
for (i in p8) {
|
||||||
|
xs.add(i)
|
||||||
|
if (xs.size > 23) break
|
||||||
|
}
|
||||||
|
if (xs.size > 0) {
|
||||||
|
throw AssertionError("Wrong elements for MaxUI..MinUI: $xs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
testSimpleUIntLoop()
|
||||||
|
testEmptyUIntLoop()
|
||||||
|
testSimpleULongLoop()
|
||||||
|
testEmptyULongLoop()
|
||||||
|
testULongLoop()
|
||||||
|
testEmptyULongLoop2()
|
||||||
|
testMaxUIdownToMinUI()
|
||||||
|
testMaxULdownToMinUL()
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
const val MaxUI = UInt.MAX_VALUE
|
||||||
|
const val MinUI = UInt.MIN_VALUE
|
||||||
|
|
||||||
|
const val MaxUL = ULong.MAX_VALUE
|
||||||
|
const val MinUL = ULong.MIN_VALUE
|
||||||
|
|
||||||
|
val M = MaxUI.toULong()
|
||||||
|
|
||||||
|
val range1 = 1u .. 6u
|
||||||
|
fun testSimpleUIntLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range1) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 123456) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range2 = 6u .. 1u
|
||||||
|
fun testEmptyUIntLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range2) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range3 = 1UL .. 6UL
|
||||||
|
fun testSimpleULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range3) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 123456) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range4 = 6UL .. 1UL
|
||||||
|
fun testEmptyULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range4) {
|
||||||
|
s = s*10 + i.toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range5 = M+1UL..M+6UL
|
||||||
|
fun testULongLoop() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range5) {
|
||||||
|
s = s*10 + (i-M).toInt()
|
||||||
|
}
|
||||||
|
if (s != 123456) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range6 = M+6UL..M+1UL
|
||||||
|
fun testEmptyULongLoop2() {
|
||||||
|
var s = 0
|
||||||
|
for (i in range6) {
|
||||||
|
s = s*10 + (i-M).toInt()
|
||||||
|
}
|
||||||
|
if (s != 0) throw AssertionError("$s")
|
||||||
|
}
|
||||||
|
|
||||||
|
val range7 = MaxUI..MinUI
|
||||||
|
fun testMaxUItoMinUI() {
|
||||||
|
val xs = ArrayList<UInt>()
|
||||||
|
for (i in range7) {
|
||||||
|
xs.add(i)
|
||||||
|
if (xs.size > 23) break
|
||||||
|
}
|
||||||
|
if (xs.size > 0) {
|
||||||
|
throw AssertionError("Wrong elements for MaxUI..MinUI: $xs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val range8 = MaxUL..MinUL
|
||||||
|
fun testMaxULtoMinUL() {
|
||||||
|
val xs = ArrayList<ULong>()
|
||||||
|
for (i in range8) {
|
||||||
|
xs.add(i)
|
||||||
|
if (xs.size > 23) break
|
||||||
|
}
|
||||||
|
if (xs.size > 0) {
|
||||||
|
throw AssertionError("Wrong elements for MaxUI..MinUI: $xs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
testSimpleUIntLoop()
|
||||||
|
testEmptyUIntLoop()
|
||||||
|
testSimpleULongLoop()
|
||||||
|
testEmptyULongLoop()
|
||||||
|
testULongLoop()
|
||||||
|
testEmptyULongLoop2()
|
||||||
|
testMaxUItoMinUI()
|
||||||
|
testMaxULtoMinUL()
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+10
@@ -24198,6 +24198,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedProgression.kt")
|
||||||
|
public void testForInUnsignedProgression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedProgression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedRange.kt")
|
||||||
|
public void testForInUnsignedRange() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRange.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
||||||
public void testForInUnsignedRangeLiteral() throws Exception {
|
public void testForInUnsignedRangeLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
||||||
|
|||||||
+10
@@ -24198,6 +24198,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedProgression.kt")
|
||||||
|
public void testForInUnsignedProgression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedProgression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedRange.kt")
|
||||||
|
public void testForInUnsignedRange() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRange.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
||||||
public void testForInUnsignedRangeLiteral() throws Exception {
|
public void testForInUnsignedRangeLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
||||||
|
|||||||
+10
@@ -24203,6 +24203,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedProgression.kt")
|
||||||
|
public void testForInUnsignedProgression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedProgression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedRange.kt")
|
||||||
|
public void testForInUnsignedRange() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRange.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
||||||
public void testForInUnsignedRangeLiteral() throws Exception {
|
public void testForInUnsignedRangeLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
||||||
|
|||||||
+10
@@ -18648,6 +18648,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedProgression.kt")
|
||||||
|
public void testForInUnsignedProgression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedProgression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedRange.kt")
|
||||||
|
public void testForInUnsignedRange() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRange.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
||||||
public void testForInUnsignedRangeLiteral() throws Exception {
|
public void testForInUnsignedRangeLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
||||||
|
|||||||
+10
@@ -19698,6 +19698,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedDownTo.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedProgression.kt")
|
||||||
|
public void testForInUnsignedProgression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedProgression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("forInUnsignedRange.kt")
|
||||||
|
public void testForInUnsignedRange() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRange.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
@TestMetadata("forInUnsignedRangeLiteral.kt")
|
||||||
public void testForInUnsignedRangeLiteral() throws Exception {
|
public void testForInUnsignedRangeLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedRangeLiteral.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user