ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.71k stars 2.47k forks source link

Slice operations `slice_sentinel` and `slice_length` (with sentinel) produce compile-time assertions testing incorrect (overestimated) upper bounds #19795

Open amp-59 opened 4 months ago

amp-59 commented 4 months ago

Zig Version

0.13.0-dev.46+3648d7df1

Steps to Reproduce and Observed Behaviour

Compile and run example program with zig run overestimate_upper_bound.zig overestimate_upper_bound.zig:

var src_mem: [3]u8 = .{ 0, 0, 0 };
pub fn main() void {
    const src_ptr: *[3]u8 = src_mem[0..3];
    _ = src_ptr[1..3 :1];
    _ = src_ptr[1..][0..2 :1];
}

Output:

zig run overestimate_upper_bound.zig

The program compiles normally, then the program runs and also exits normally.

Expected Behaviour

The compile error condition should match the runtime panic condition.

Interestingly, if either start operand is a runtime value (1) the program will panic at runtime with the correct condition.

This is still an inadequate outcome for the slice_end (with sentinel) variant, because the success condition is known to be impossible at compile time.

amp-59 commented 4 months ago

I should also probably point out that the user could inspect this code and conclude that the compiler had produced undefined behaviour in order to check the sentinel value, because the sentinel index (3) for both slices is obviously out of bounds, and because there is not even that much memory in the containing declaration.

However, this does not actually occur because of another bug (#19792) that causes the compiler to give up checking sentinels for comptime pointers when the memory pointed to is known at runtime.