diff --git a/generators/builtins/unsignedTypes.kt b/generators/builtins/unsignedTypes.kt index 57b70e3706a..ed926982d7e 100644 --- a/generators/builtins/unsignedTypes.kt +++ b/generators/builtins/unsignedTypes.kt @@ -341,6 +341,7 @@ class UnsignedRangeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIn val elementType = type.capitalized val signedType = type.asSigned.capitalized val stepType = signedType + val stepMinValue = "$stepType.MIN_VALUE" override fun getPackage(): String = "kotlin.ranges" @@ -393,7 +394,8 @@ internal constructor( step: $stepType ) : Iterable<$elementType> { init { - if (step == 0.to$stepType()) throw kotlin.IllegalArgumentException("Step must be non-zero") + if (step == 0.to$stepType()) throw kotlin.IllegalArgumentException("Step must be non-zero.") + if (step == $stepMinValue) throw kotlin.IllegalArgumentException("Step must be greater than $stepMinValue to avoid overflow on negation.") } /** @@ -431,6 +433,8 @@ internal constructor( * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. + * + * [step] must be greater than `$stepMinValue` and not equal to zero. */ public fun fromClosedRange(rangeStart: $elementType, rangeEnd: $elementType, step: $stepType): ${elementType}Progression = ${elementType}Progression(rangeStart, rangeEnd, step) } diff --git a/libraries/stdlib/test/ranges/RangeTest.kt b/libraries/stdlib/test/ranges/RangeTest.kt index bec49780399..6779bc2324b 100644 --- a/libraries/stdlib/test/ranges/RangeTest.kt +++ b/libraries/stdlib/test/ranges/RangeTest.kt @@ -385,5 +385,7 @@ public class RangeTest { assertFailsWithIllegalArgument { CharProgression.fromClosedRange('a', 'b', Int.MIN_VALUE) } assertFailsWithIllegalArgument { IntProgression.fromClosedRange(0, 1, Int.MIN_VALUE) } assertFailsWithIllegalArgument { LongProgression.fromClosedRange(0, 1, Long.MIN_VALUE) } + assertFailsWithIllegalArgument { UIntProgression.fromClosedRange(0u, 1u, Int.MIN_VALUE) } + assertFailsWithIllegalArgument { ULongProgression.fromClosedRange(0u, 1u, Long.MIN_VALUE) } } } diff --git a/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt b/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt index bbba3e3058b..dc2670df566 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt @@ -51,7 +51,8 @@ internal constructor( step: Int ) : Iterable { init { - if (step == 0.toInt()) throw kotlin.IllegalArgumentException("Step must be non-zero") + if (step == 0.toInt()) throw kotlin.IllegalArgumentException("Step must be non-zero.") + if (step == Int.MIN_VALUE) throw kotlin.IllegalArgumentException("Step must be greater than Int.MIN_VALUE to avoid overflow on negation.") } /** @@ -89,6 +90,8 @@ internal constructor( * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. + * + * [step] must be greater than `Int.MIN_VALUE` and not equal to zero. */ public fun fromClosedRange(rangeStart: UInt, rangeEnd: UInt, step: Int): UIntProgression = UIntProgression(rangeStart, rangeEnd, step) } diff --git a/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt b/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt index fc0ef2ef591..3811a24bb09 100644 --- a/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt +++ b/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt @@ -51,7 +51,8 @@ internal constructor( step: Long ) : Iterable { init { - if (step == 0.toLong()) throw kotlin.IllegalArgumentException("Step must be non-zero") + if (step == 0.toLong()) throw kotlin.IllegalArgumentException("Step must be non-zero.") + if (step == Long.MIN_VALUE) throw kotlin.IllegalArgumentException("Step must be greater than Long.MIN_VALUE to avoid overflow on negation.") } /** @@ -89,6 +90,8 @@ internal constructor( * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. + * + * [step] must be greater than `Long.MIN_VALUE` and not equal to zero. */ public fun fromClosedRange(rangeStart: ULong, rangeEnd: ULong, step: Long): ULongProgression = ULongProgression(rangeStart, rangeEnd, step) }