Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiler crash writing pointer to comptime var to reinterpreted memory #21216

Open
rohlem opened this issue Aug 27, 2024 · 2 comments
Open

compiler crash writing pointer to comptime var to reinterpreted memory #21216

rohlem opened this issue Aug 27, 2024 · 2 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@rohlem
Copy link
Contributor

rohlem commented Aug 27, 2024

Zig Version

0.14.0-dev.617+208baa37c

Steps to Reproduce and Observed Behavior

(For context, I was basically playing around with a userland implementation of a safety feature to simulate the pinned struct/type feature proposed in #7769.)
minimized repro:

const P = packed struct {
    p: *P,
};
comptime {
    var buffer: [@sizeOf(P)]u8 align(@alignOf(P)) = undefined;
    const s: *P = @ptrCast(&buffer);
    s.p = s;
}

zig test .zig outputs a brief progress display, then crashes (exits with non-0 exit code).

Expected Behavior

Certainly the compiler shouldn't crash.
The same code is valid at runtime (if you change the comptime block to a test block), so ideally I'd like it to work at comptime.

I agree that it's tricky though, the compiler would have to implement some serialization / bit representation of comptime-only pointers (if that doesn't exist yet).
To be fully deterministic it should also assert that none of the bits used here escape to program runtime,
i.e. the memory should not be allowed into runtime.
(Though as a further improvement, if all affected bits have been overwritten, it should then again be allowed into runtime.)
Because of that complexity I expect the most likely short-term resolution to be a compile error that blocks this code from executing at comptime.
A workaround would have to check @inComptime() and replace the affected logic with manual bookkeeping of some sort.

Note that equivalent reinterpreting code using packed union leads to the other union fields being treated as a runtime value,
and only crashes if trying to read these bits at runtime:

const P2 = packed union {
    buffer: @Type(.{ .Int = .{
        .signedness = .unsigned,
        .bits = 8 * @sizeOf(*P2),
    } }),
    p: *P2,
};
test {
    comptime var b: P2 = undefined;
    const s = &b;
    s.p = s;
    //@compileLog(s.buffer); //@as(u64, [runtime value])
    comptime {
        //_ = s.buffer + 2; //treated as runtime value, correctly triggers `error: unable to evaluate comptime expression`
    }
    var x = s.buffer; //crashes
    _ = &x;
}
@rohlem rohlem added the bug Observed behavior contradicts documented or intended behavior label Aug 27, 2024
@Vexu
Copy link
Member

Vexu commented Aug 27, 2024

That reduction looks like a duplicate of #20765, not sure if fixing that would fix the other example.

@rohlem
Copy link
Contributor Author

rohlem commented Aug 27, 2024

Might be related, although from a quick glance I don't see the code in the other issue writing a pointer value to a reinterpreted buffer.
Regardless, the repro here is shorter and doesn't depend on std, so I assume it would be easier to track down/reduce, for what it's worth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants