From ee80e0b8ca6182e9bd60fe0f3d90642db9c3a5da Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Jun 2013 19:41:38 +0400 Subject: [PATCH] Fix loops over progressions near to MAX_VALUE/MIN_VALUE #KT-492 Fixed For Byte, Char and Short ranges, promote the type of the loop parameter to int to avoid overflows. For Int and Long ranges at the end of the loop over a progression we now check if the new (incremented) value of the loop parameter is greater than the old value iff increment > 0 --- .../org/jetbrains/jet/codegen/AsmUtil.java | 22 +++++- .../jet/codegen/ExpressionCodegen.java | 62 +++++++++++++--- .../org/jetbrains/jet/codegen/StackValue.java | 16 +---- .../expression/inexactDownToMinValue.kt | 68 ++++++++++++++++++ .../ranges/expression/inexactToMaxValue.kt | 68 ++++++++++++++++++ .../expression/progressionDownToMinValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueMinusTwoToMaxValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueToMaxValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueToMinValue.kt | 68 ++++++++++++++++++ .../progressionMinValueToMinValue.kt | 68 ++++++++++++++++++ .../ranges/literal/inexactDownToMinValue.kt | 63 +++++++++++++++++ .../ranges/literal/inexactToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionDownToMinValue.kt | 63 +++++++++++++++++ .../progressionMaxValueMinusTwoToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionMaxValueToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionMaxValueToMinValue.kt | 63 +++++++++++++++++ .../literal/progressionMinValueToMinValue.kt | 63 +++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 70 +++++++++++++++++++ .../tests/GenerateRangesCodegenTestData.java | 4 ++ .../test/language/RangeIterationTest.kt | 63 +++++++++++++++++ runtime/src/jet/ByteProgressionIterator.java | 6 +- runtime/src/jet/CharProgressionIterator.java | 6 +- runtime/src/jet/IntProgressionIterator.java | 6 +- runtime/src/jet/LongProgressionIterator.java | 6 +- runtime/src/jet/ShortProgressionIterator.java | 6 +- 25 files changed, 1148 insertions(+), 36 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index a2c63c40d4f..9116696fa30 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -47,9 +47,7 @@ import java.util.Set; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isKindOf; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; public class AsmUtil { @@ -642,4 +640,22 @@ public class AsmUtil { return Type.INT_TYPE; } + public static void pop(@NotNull InstructionAdapter v, @NotNull Type type) { + if (type.getSize() == 2) { + v.pop2(); + } + else { + v.pop(); + } + } + + public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) { + if (type.getSize() == 2) { + v.dup2(); + } + else { + v.dup(); + } + } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1ae21c4ccd2..66edba467db 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1108,20 +1108,69 @@ public class ExpressionCodegen extends JetVisitor implem @Override protected void increment(@NotNull Label loopExit) { - v.load(loopParameterVar, asmElementType); v.load(incrementVar, asmElementType); v.add(asmElementType); int sort = asmElementType.getSort(); - if (sort == Type.CHAR || sort == Type.BYTE || sort == Type.SHORT) { - StackValue.coerce(Type.INT_TYPE, asmElementType, v); + if (sort == Type.INT || sort == Type.LONG) { + checkNewLoopParameterValue(loopExit); } v.store(loopParameterVar, asmElementType); } + + // Checks that (increment > 0) == (new value of loop parameter > old value of loop parameter). + // Old value should be stored in loopParameterVar, new value should be on top of the stack + private void checkNewLoopParameterValue(@NotNull Label loopExit) { + Label negativeIncrement = new Label(); + Label afterIf = new Label(); + Label popAndExit = new Label(); + + dup(v, asmElementType); + v.load(loopParameterVar, asmElementType); + + v.load(incrementVar, asmElementType); + + if (asmElementType.getSort() == Type.LONG) { + v.lconst(0L); + v.lcmp(); + v.ifle(negativeIncrement); + + // increment > 0 + v.lcmp(); + v.iflt(popAndExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.lcmp(); + v.ifgt(popAndExit); + v.goTo(afterIf); + } + else { + v.ifle(negativeIncrement); + + // increment > 0 + v.ificmplt(popAndExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.ificmpgt(popAndExit); + v.goTo(afterIf); + } + + // Pop the new value of loop parameter from the stack and exit the loop + v.mark(popAndExit); + pop(v, asmElementType); + v.goTo(loopExit); + + v.mark(afterIf); + } } + @Override public StackValue visitBreakExpression(JetBreakExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); @@ -3059,12 +3108,7 @@ public class ExpressionCodegen extends JetVisitor implem switch (value.receiverSize()) { case 0: - if (type.getSize() == 2) { - v.dup2(); - } - else { - v.dup(); - } + dup(v, type); break; case 1: diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index db0639e04af..89b63089c40 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; -import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -211,15 +210,6 @@ public abstract class StackValue { } } - private static void pop(Type type, InstructionAdapter v) { - if (type.getSize() == 1) { - v.pop(); - } - else { - v.pop2(); - } - } - protected void coerceTo(Type toType, InstructionAdapter v) { coerce(this.type, toType, v); } @@ -232,7 +222,7 @@ public abstract class StackValue { if (toType.equals(fromType)) return; if (toType.getSort() == Type.VOID) { - pop(fromType, v); + pop(v, fromType); } else if (fromType.getSort() == Type.VOID) { if (toType.equals(JET_UNIT_TYPE) || toType.equals(OBJECT_TYPE)) { @@ -246,7 +236,7 @@ public abstract class StackValue { } } else if (toType.equals(JET_UNIT_TYPE)) { - pop(fromType, v); + pop(v, fromType); putUnitInstance(v); } else if (toType.getSort() == Type.ARRAY) { @@ -646,7 +636,7 @@ public abstract class StackValue { method.invokeWithNotNullAssertion(v, state, resolvedSetCall); Type returnType = asmMethod.getReturnType(); if (returnType != Type.VOID_TYPE) { - pop(returnType, v); + pop(v, returnType); } } else { diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt new file mode 100644 index 00000000000..c7f0bf53896 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 5) downTo MinI step 3 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 5).toByte() downTo MinB step 3 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 5).toByte(), (MinB + 2).toByte())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 5).toShort() downTo MinS step 3 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 5).toShort(), (MinS + 2).toShort())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 5).toLong() downTo MinL step 3 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 5).toChar() downTo MinC step 3 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 5).toChar(), (MinC + 2).toChar())) { + return "Wrong elements for (MinC + 5).toChar() downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt new file mode 100644 index 00000000000..18c099542cc --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 5)..MaxI step 3 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 5).toByte()..MaxB step 3 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 5).toShort()..MaxS step 3 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 5).toLong()..MaxL step 3 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 5).toChar()..MaxC step 3 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) { + return "Wrong elements for (MaxC - 5).toChar()..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt new file mode 100644 index 00000000000..4784f93dc6b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 2) downTo MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 2).toByte() downTo MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 2).toShort() downTo MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 2).toLong() downTo MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 2).toChar() downTo MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) { + return "Wrong elements for (MinC + 2).toChar() downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..58a8f51eb91 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 2)..MaxI step 2 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 2).toByte()..MaxB step 2 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 2).toShort()..MaxS step 2 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 2).toLong()..MaxL step 2 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 2).toChar()..MaxC step 2 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..f98142eb761 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MaxI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MaxB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MaxS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MaxL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MaxC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..f98fa931b5f --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..841e4a2f972 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MinI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MinB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MinB)) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MinS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MinS)) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MinL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MinC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt new file mode 100644 index 00000000000..377f478c9d4 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 5) downTo MinI step 3) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 5).toByte() downTo MinB step 3) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 5).toByte(), (MinB + 2).toByte())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 5).toShort() downTo MinS step 3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 5).toShort(), (MinS + 2).toShort())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 5).toLong() downTo MinL step 3) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 5).toChar() downTo MinC step 3) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 5).toChar(), (MinC + 2).toChar())) { + return "Wrong elements for (MinC + 5).toChar() downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt new file mode 100644 index 00000000000..d587c6179c7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 5)..MaxI step 3) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 5).toByte()..MaxB step 3) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 5).toShort()..MaxS step 3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 5).toLong()..MaxL step 3) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 5).toChar()..MaxC step 3) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) { + return "Wrong elements for (MaxC - 5).toChar()..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt new file mode 100644 index 00000000000..c46ecb75624 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 2) downTo MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 2).toByte() downTo MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 2).toShort() downTo MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 2).toLong() downTo MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 2).toChar() downTo MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) { + return "Wrong elements for (MinC + 2).toChar() downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..6898b60201c --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 2)..MaxI step 2) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 2).toByte()..MaxB step 2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 2).toShort()..MaxS step 2) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 2).toLong()..MaxL step 2) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 2).toChar()..MaxC step 2) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..273c3f130c0 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MaxI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MaxB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MaxS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MaxL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MaxC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..a3c79c8f816 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..88400d8192a --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MinI..MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MinB..MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MinB)) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MinS..MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MinS)) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MinL..MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MinC..MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 26cc88726d3..540c6ab73aa 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -424,6 +424,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt"); } + @TestMetadata("inexactDownToMinValue.kt") + public void testInexactDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt"); + } + @TestMetadata("inexactSteppedDownTo.kt") public void testInexactSteppedDownTo() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt"); @@ -434,6 +439,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt"); } + @TestMetadata("inexactToMaxValue.kt") + public void testInexactToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt"); + } + @TestMetadata("infiniteSteps.kt") public void testInfiniteSteps() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt"); @@ -469,6 +479,31 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt"); } + @TestMetadata("progressionDownToMinValue.kt") + public void testProgressionDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt"); + } + + @TestMetadata("progressionMaxValueMinusTwoToMaxValue.kt") + public void testProgressionMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMaxValue.kt") + public void testProgressionMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMinValue.kt") + public void testProgressionMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt"); + } + + @TestMetadata("progressionMinValueToMinValue.kt") + public void testProgressionMinValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt"); + } + @TestMetadata("reversedBackSequence.kt") public void testReversedBackSequence() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt"); @@ -542,6 +577,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt"); } + @TestMetadata("inexactDownToMinValue.kt") + public void testInexactDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt"); + } + @TestMetadata("inexactSteppedDownTo.kt") public void testInexactSteppedDownTo() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt"); @@ -552,6 +592,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt"); } + @TestMetadata("inexactToMaxValue.kt") + public void testInexactToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt"); + } + @TestMetadata("infiniteSteps.kt") public void testInfiniteSteps() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt"); @@ -587,6 +632,31 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt"); } + @TestMetadata("progressionDownToMinValue.kt") + public void testProgressionDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt"); + } + + @TestMetadata("progressionMaxValueMinusTwoToMaxValue.kt") + public void testProgressionMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMaxValue.kt") + public void testProgressionMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMinValue.kt") + public void testProgressionMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt"); + } + + @TestMetadata("progressionMinValueToMinValue.kt") + public void testProgressionMinValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt"); + } + @TestMetadata("reversedBackSequence.kt") public void testReversedBackSequence() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt"); diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java index fabedee33f9..75a7235299e 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java @@ -68,9 +68,13 @@ public class GenerateRangesCodegenTestData { .put("Float.NaN", "Float") .put("Double.NaN", "Double") .put("MaxB", "Byte") + .put("MinB", "Byte") .put("MaxS", "Short") + .put("MinS", "Short") .put("MaxL", "Long") + .put("MinL", "Long") .put("MaxC", "Char") + .put("MinC", "Char") .build(); private static String detectElementType(String rangeExpression) { diff --git a/libraries/stdlib/test/language/RangeIterationTest.kt b/libraries/stdlib/test/language/RangeIterationTest.kt index 37fcd7e9e48..7806eb9b6f6 100644 --- a/libraries/stdlib/test/language/RangeIterationTest.kt +++ b/libraries/stdlib/test/language/RangeIterationTest.kt @@ -318,4 +318,67 @@ public class RangeIterationTest { doTest(MaxC..MinC, MaxC, MinC, 1, listOf()) } + + test fun progressionMaxValueToMaxValue() { + doTest(MaxI..MaxI step 1, MaxI, MaxI, 1, listOf(MaxI)) + doTest(MaxB..MaxB step 1, MaxB, MaxB, 1, listOf(MaxB)) + doTest(MaxS..MaxS step 1, MaxS, MaxS, 1, listOf(MaxS)) + doTest(MaxL..MaxL step 1, MaxL, MaxL, 1.toLong(), listOf(MaxL)) + + doTest(MaxC..MaxC step 1, MaxC, MaxC, 1, listOf(MaxC)) + } + + test fun progressionMaxValueMinusTwoToMaxValue() { + doTest((MaxI - 2)..MaxI step 2, MaxI - 2, MaxI, 2, listOf(MaxI - 2, MaxI)) + doTest((MaxB - 2).toByte()..MaxB step 2, (MaxB - 2).toByte(), MaxB, 2, listOf((MaxB - 2).toByte(), MaxB)) + doTest((MaxS - 2).toShort()..MaxS step 2, (MaxS - 2).toShort(), MaxS, 2, listOf((MaxS - 2).toShort(), MaxS)) + doTest((MaxL - 2).toLong()..MaxL step 2, (MaxL - 2).toLong(), MaxL, 2.toLong(), listOf((MaxL - 2).toLong(), MaxL)) + + doTest((MaxC - 2).toChar()..MaxC step 2, (MaxC - 2).toChar(), MaxC, 2, listOf((MaxC - 2).toChar(), MaxC)) + } + + test fun progressionMaxValueToMinValue() { + doTest(MaxI..MinI step 1, MaxI, MinI, 1, listOf()) + doTest(MaxB..MinB step 1, MaxB, MinB, 1, listOf()) + doTest(MaxS..MinS step 1, MaxS, MinS, 1, listOf()) + doTest(MaxL..MinL step 1, MaxL, MinL, 1.toLong(), listOf()) + + doTest(MaxC..MinC step 1, MaxC, MinC, 1, listOf()) + } + + test fun progressionMinValueToMinValue() { + doTest(MinI..MinI step 1, MinI, MinI, 1, listOf(MinI)) + doTest(MinB..MinB step 1, MinB, MinB, 1, listOf(MinB)) + doTest(MinS..MinS step 1, MinS, MinS, 1, listOf(MinS)) + doTest(MinL..MinL step 1, MinL, MinL, 1.toLong(), listOf(MinL)) + + doTest(MinC..MinC step 1, MinC, MinC, 1, listOf(MinC)) + } + + test fun inexactToMaxValue() { + doTest((MaxI - 5)..MaxI step 3, MaxI - 5, MaxI, 3, listOf(MaxI - 5, MaxI - 2)) + doTest((MaxB - 5).toByte()..MaxB step 3, (MaxB - 5).toByte(), MaxB, 3, listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) + doTest((MaxS - 5).toShort()..MaxS step 3, (MaxS - 5).toShort(), MaxS, 3, listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) + doTest((MaxL - 5).toLong()..MaxL step 3, (MaxL - 5).toLong(), MaxL, 3.toLong(), listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) + + doTest((MaxC - 5).toChar()..MaxC step 3, (MaxC - 5).toChar(), MaxC, 3, listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) + } + + test fun progressionDownToMinValue() { + doTest((MinI + 2) downTo MinI step 1, MinI + 2, MinI, -1, listOf(MinI + 2, MinI + 1, MinI)) + doTest((MinB + 2).toByte() downTo MinB step 1, (MinB + 2).toByte(), MinB, -1, listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) + doTest((MinS + 2).toShort() downTo MinS step 1, (MinS + 2).toShort(), MinS, -1, listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) + doTest((MinL + 2).toLong() downTo MinL step 1, (MinL + 2).toLong(), MinL, -1.toLong(), listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) + + doTest((MinC + 2).toChar() downTo MinC step 1, (MinC + 2).toChar(), MinC, -1, listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) + } + + test fun inexactDownToMinValue() { + doTest((MinI + 5) downTo MinI step 3, MinI + 5, MinI, -3, listOf(MinI + 5, MinI + 2)) + doTest((MinB + 5).toByte() downTo MinB step 3, (MinB + 5).toByte(), MinB, -3, listOf((MinB + 5).toByte(), (MinB + 2).toByte())) + doTest((MinS + 5).toShort() downTo MinS step 3, (MinS + 5).toShort(), MinS, -3, listOf((MinS + 5).toShort(), (MinS + 2).toShort())) + doTest((MinL + 5).toLong() downTo MinL step 3, (MinL + 5).toLong(), MinL, -3.toLong(), listOf((MinL + 5).toLong(), (MinL + 2).toLong())) + + doTest((MinC + 5).toChar() downTo MinC step 3, (MinC + 5).toChar(), MinC, -3, listOf((MinC + 5).toChar(), (MinC + 2).toChar())) + } } diff --git a/runtime/src/jet/ByteProgressionIterator.java b/runtime/src/jet/ByteProgressionIterator.java index e2989bc789c..85243e18f2f 100644 --- a/runtime/src/jet/ByteProgressionIterator.java +++ b/runtime/src/jet/ByteProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class ByteProgressionIterator extends ByteIterator { - private byte next; + private int next; private final byte end; private final int increment; @@ -34,8 +34,8 @@ class ByteProgressionIterator extends ByteIterator { @Override public byte nextByte() { - byte value = next; + int value = next; next += increment; - return value; + return (byte) value; } } diff --git a/runtime/src/jet/CharProgressionIterator.java b/runtime/src/jet/CharProgressionIterator.java index 49f8dab710f..dc608162f9f 100644 --- a/runtime/src/jet/CharProgressionIterator.java +++ b/runtime/src/jet/CharProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class CharProgressionIterator extends CharIterator { - private char next; + private int next; private final char end; private final int increment; @@ -34,8 +34,8 @@ class CharProgressionIterator extends CharIterator { @Override public char nextChar() { - char value = next; + int value = next; next += increment; - return value; + return (char) value; } } diff --git a/runtime/src/jet/IntProgressionIterator.java b/runtime/src/jet/IntProgressionIterator.java index 21845098713..3d7dda17af8 100644 --- a/runtime/src/jet/IntProgressionIterator.java +++ b/runtime/src/jet/IntProgressionIterator.java @@ -20,6 +20,7 @@ class IntProgressionIterator extends IntIterator { private int next; private final int end; private final int increment; + private boolean overflowHappened = false; public IntProgressionIterator(int start, int end, int increment) { this.next = start; @@ -29,13 +30,16 @@ class IntProgressionIterator extends IntIterator { @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return !overflowHappened && (increment > 0 ? next <= end : next >= end); } @Override public int nextInt() { int value = next; next += increment; + if ((increment > 0) != (next > value)) { + overflowHappened = true; + } return value; } } diff --git a/runtime/src/jet/LongProgressionIterator.java b/runtime/src/jet/LongProgressionIterator.java index 71fc911794d..f6c613cf3fa 100644 --- a/runtime/src/jet/LongProgressionIterator.java +++ b/runtime/src/jet/LongProgressionIterator.java @@ -20,6 +20,7 @@ class LongProgressionIterator extends LongIterator { private long next; private final long end; private final long increment; + private boolean overflowHappened = false; public LongProgressionIterator(long start, long end, long increment) { this.next = start; @@ -29,13 +30,16 @@ class LongProgressionIterator extends LongIterator { @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return !overflowHappened && (increment > 0 ? next <= end : next >= end); } @Override public long nextLong() { long value = next; next += increment; + if ((increment > 0) != (next > value)) { + overflowHappened = true; + } return value; } } diff --git a/runtime/src/jet/ShortProgressionIterator.java b/runtime/src/jet/ShortProgressionIterator.java index 3b7bf8cf4f5..cd3b77200f9 100644 --- a/runtime/src/jet/ShortProgressionIterator.java +++ b/runtime/src/jet/ShortProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class ShortProgressionIterator extends ShortIterator { - private short next; + private int next; private final short end; private final int increment; @@ -34,8 +34,8 @@ class ShortProgressionIterator extends ShortIterator { @Override public short nextShort() { - short value = next; + int value = next; next += increment; - return value; + return (short) value; } }