ocaml-stdint
ocaml-stdint copied to clipboard
Test failures with 0.7.0
I'm trying to build version 0.7.0 for Fedora. I'm seeing multiple test failures building on an x86_64 Fedora Rawhide machine, with OCaml 4.11.1 and gcc 10.2.1.
In tests/stdint_test.ml, pos_int can return a value outside of the allowed range. For example, with Int8, in_range picks a value between -128 and 127. Let's say it picks -128. Then pos_int takes the absolute value, which is 128, and returns that. This causes some test failures because the OCaml integer version works with the value 128, but the Int8 version works with 128 converted to an Int8, which is -127. Shouldn't pos_int pick from the range 0 to maxi instead?
Other test failures are caused by the definition of lognot in lib/stdint.ml. In modules Int40, Int48, Int56, and Int128, lognot is defined as logxor max_int. But that leaves the sign bit unchanged. It should do the XOR operation with -1 instead. Here's the output from a little code I wrote. For each type T, the number on the left of the comma is the result of Stdint.T.to_string (Stdint.T.lognot (Stdint.T.of_int 0)), and the number on the right of the comma is the result of Stdint.T.to_string (Stdint.T.of_int (lnot 0)). They should be the same.
Int8: -1, -1
Int16: -1, -1
Int24: -1, -1
Int32: -1, -1
Int40: 549755813887, -1
Int48: 140737488355327, -1
Int56: 36028797018963967, -1
Int64: -1, -1
Int128: 170141183460469231731687303715884105727, -1
Uint8: 255, 255
Uint16: 65535, 65535
Uint24: 16777215, 16777215
Uint32: 4294967295, 4294967295
Uint40: 1099511627775, 1099511627775
Uint48: 281474976710655, 281474976710655
Uint56: 72057594037927935, 72057594037927935
Uint64: 18446744073709551615, 18446744073709551615
Uint128: 340282366920938463463374607431768211455, 340282366920938463463374607431768211455
I'm getting other test failures that I haven't diagnosed yet:
== Testing Int64 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 45 shrink steps)
== Testing Int128 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 37 shrink steps)
test `Logical shifts must not sign-extend` failed on ≥ 1 cases:
0 (after 9 shrink steps)
== Testing Uint64 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 38 shrink steps)
== Testing Uint128 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 37 shrink steps)
Regarding the left shift tests, for each type T, this table shows the result of Stdint.T.shift_left (Stdint.T.of_int 70368744177664) 16) on the left, and the result of Stdint.T.of_int (70368744177664 lsl 16)) on the right. I have translated to hex to make it easier to see what's happening. Note that 70368744177664 is 0x400000000000.
Int64: 0x4000000000000000, -0x4000000000000000
Uint64: 0x4000000000000000, 0xc000000000000000
Int128: 0x4000000000000000, -0x4000000000000000
Uint128: 0x4000000000000000, 0xc0000000000000000000000000000000
So stdint is computing the correct result, but the comparison with OCaml operations is failing, because OCaml doesn't do what this test expects. The value of (70368744177664 lsl 16) is -4611686018427387904; i.e., -0x4000000000000000, the most negative integer OCaml can represent in 63 bits. The bug here seems to be that the test code thinks OCaml integers are 64-bit, but they are only 63-bit.
Regarding the failing "logical shifts must not sign-extend" test, 0 is one of the values that can be picked for the right shift. The minimum integer for a signed type right shifted by 0 is still the minimum integer; i.e., a negative value. Shouldn't that test be choosing from (int_range 1 200) rather than (int_range 0 200)?
Getting the following failures on NixOS with OCaml 4.10 (with 0.7.0 not master):
== Testing Int40 ==
test `An integer should perform logical-not correctly` failed on ≥ 1 cases:
0 (after 38 shrink steps)
== Testing Int48 ==
test `An integer should perform logical-not correctly` failed on ≥ 1 cases:
0 (after 48 shrink steps)
== Testing Int56 ==
test `An integer should perform logical-not correctly` failed on ≥ 1 cases:
0 (after 55 shrink steps)
== Testing Int64 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 45 shrink steps)
== Testing Int128 ==
test `An integer should perform logical-not correctly` failed on ≥ 1 cases:
0 (after 59 shrink steps)
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(-70368744177665, 16) (after 34 shrink steps)
test `Logical shifts must not sign-extend` failed on ≥ 1 cases:
0 (after 9 shrink steps)
== Testing Uint64 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 38 shrink steps)
== Testing Uint128 ==
test `An integer should perform left-shifts correctly` failed on ≥ 1 cases:
(70368744177664, 16) (after 37 shrink steps)
fc64293f99f597cdfd4470954da6fb323988e2af fixes the tests for all cases except Int64, Int128, Uint64 and Uint128.