-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
I was playing around with zig, to see how it handled large bitwise left shifts, as these operations can easily produce very large value with arbitrary-precision integers, with a massive memory footprint.
I think I may have discovered two separate errors relating to this.
One is where zig uses a massive amount of memory, which I'm assuming is to calculate the result of a left shift. In this case the compiler either is terminated by the system, or exits with "error: OutOfMemory".
The other is where an even larger shift is somehow entirely ignored, and the result is seemingly the left operand of the shift.
The minimum to reproduce the memory issue is:
export fn function(num: u32) u32 {
const x: u32 = (123 << 1000000000000) - 2;
return num * x;
}The result should take up ~116GB, so given time, it may succeed on some machines.
The minimum to reproduce the unshifted output value is:
export fn function(num: u32) u32 {
const z: u32 = (123 << 10000000000000000000001) - 2;
return num * z;
}At first I used 10000000000000000000000, and thought perhaps the compiler was being clever, since 32 is a divisor of 10000000000000000000000, but the result was unchanged by adding 1 to the shift amount.
I have reproduced these errors locally with zig 0.13.0, and with 0.13.0 and trunk on godbolt.org
Expected Behavior
From the documentation, I wasn't able to determine the exact semantics of the bitwise left shift. If the result is defined as shifting the value by the shift amount, modulo the bit width of the operand, then shifts should not be possible for comptime_int, and should not be folded until assigned a type.
If bitwise left shift is defined as the value shifted by the shift amount, then it should either tell me that the request is ridiculous and stop, or somehow "memoize" the value as having a most significant bit at some position, and later print an error with (BigInt) as is seen for other numbers that are so large that zig won't print them
If the value being shifted is 0, then of course the result should just be 0.