ziglang / zig

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

Compiler crash subtracting pointers within the same object in a `comptime` block #21478

Closed rohlem closed 4 hours ago

rohlem commented 5 hours ago

Zig Version

0.14.0-dev.1579+f3445f8f6

Steps to Reproduce and Observed Behavior

It's possible there's a smaller repro, but I found two surprising things at once, so I stopped before maybe mis-reducing one of them Repro zig test .zig:

pub const S = struct {
    length: u2,
    data: [4]u8,
    pub fn endPointer(self: *const S) [*]const u8 {
        return &self.data[self.length];
    }
    pub fn endOffset(self: *const S) usize {
        return @offsetOf(S, "data") + self.length;
    }
};

const s: S = .{
    .length = 1,
    .data = undefined,
};
const offset1 = offset1: {
    const end_pointer = s.endPointer();
    const base_pointer: [*]const u8 = @ptrCast(&s);
    const element_pointer: [*]const u8 = @ptrCast(end_pointer);
    break :offset1 element_pointer - base_pointer;
};
const offset2 = offset2: {
    const end_pointer = &s.data[s.length];
    const base_pointer: [*]const u8 = @ptrCast(&s);
    const element_pointer: [*]const u8 = @ptrCast(end_pointer);
    break :offset2 element_pointer - base_pointer;
};
const offset3 = s.endOffset();

test {
    //@compileLog(offset1); //compiler crash
    @compileLog(offset2); //compile error: unable to evaluate comptime expression
    @compileLog(offset3); //compiles ok, to my understanding this should be equivalent to the other versions
}

Analyzing offset1 triggers a compiler crash (no output, Windows exit code -1073741819).

Commenting out offset1, analyzing offset2 (initialized from the same code with the method call inlined) instead results the following compile error:

.zig:26:36: error: unable to evaluate comptime expression
    break :offset2 element_pointer - base_pointer;
                   ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
.zig:26:36: note: operation is runtime due to this operand

This doesn't really make sense to me, because it refers to a statement inside a comptime block, where all values should be comptime-known. The compiler complains if I add an explicit unary comptime operator anywhere within the block, which prevents me from further investigation. The note "due to this operand" also doesn't point to any singular operand, which seems wrong (gives me nothing to act upon).

Expected Behavior

In my eyes the code initializing offset1, offset2, and offset3 should be equivalent and seems correct, so should be accepted and result in the same value.

rohlem commented 4 hours ago

EDIT: Actually found out the crash was related to a missing @ptrCast, I think I'll reduce them separately and reopen as separate issues.