diff --git a/core-lib/TestSuite/IntegerTests.ns b/core-lib/TestSuite/IntegerTests.ns index 5f6aac59f..a0fd57504 100644 --- a/core-lib/TestSuite/IntegerTests.ns +++ b/core-lib/TestSuite/IntegerTests.ns @@ -195,6 +195,11 @@ class IntegerTests usingPlatform: platform testFramework: minitest = ( self assert: 3 equals: 7 / 2.0. self assert: 2 equals: 7 / 3.5. + + self assert: 9223372036854775808 equals: (* Java.MIN_VALUE *) -9223372036854775808 / -1. + + (* To trigger issue, we need to compute the value, because it is otherwise parsed as a big integer *) + self assert: 9223372036854775808 equals: (* Java.MIN_VALUE *) ((-922337203685477580 * 10) - 8) / -1. ) public testDouble = ( diff --git a/src/som/primitives/arithmetic/DividePrim.java b/src/som/primitives/arithmetic/DividePrim.java index 6793d0b2c..5a6d8a309 100644 --- a/src/som/primitives/arithmetic/DividePrim.java +++ b/src/som/primitives/arithmetic/DividePrim.java @@ -12,11 +12,19 @@ @GenerateNodeFactory @Primitive(primitive = "int:divideBy:", selector = "/") public abstract class DividePrim extends ArithmeticPrim { - @Specialization + private static final BigInteger OVERFLOW_RESULT = + BigInteger.valueOf(Long.MIN_VALUE).divide(BigInteger.valueOf(-1)); + + @Specialization(guards = "!isOverflowDivision(left, right)") public final long doLong(final long left, final long right) { return left / right; } + @Specialization(guards = "isOverflowDivision(left, right)") + public final Object doLongWithOverflow(final long left, final long right) { + return OVERFLOW_RESULT; + } + @Specialization @TruffleBoundary public final Object doBigInteger(final BigInteger left, final BigInteger right) { @@ -40,4 +48,8 @@ public final Object doLong(final long left, final BigInteger right) { public final Object doLong(final long left, final double right) { return (long) (left / right); } + + protected static final boolean isOverflowDivision(final long left, final long right) { + return left == Long.MIN_VALUE && right == -1; + } }