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 panic when allocating an enum with a single field #15424

Closed
recursivetree opened this issue Apr 23, 2023 · 5 comments
Closed

Compiler panic when allocating an enum with a single field #15424

recursivetree opened this issue Apr 23, 2023 · 5 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@recursivetree
Copy link

recursivetree commented Apr 23, 2023

Zig Version

0.10.1

Steps to Reproduce and Observed Behavior

test "compiler crash"{
    const Enum = enum{A};
    const slice = try std.testing.allocator.alloc(Enum,10);
    defer std.testing.allocator.free(slice);
}

results in

/usr/local/Cellar/zig/0.10.1/lib/zig/std/mem/Allocator.zig:282:27: error: alignment must be >= 1
) Error![]align(alignment orelse @alignOf(T)) T {
                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~
thread 10545316 panic: Zig compiler bug: attempted to destroy declaration with an attached error
Unable to dump stack trace: debug info stripped
error: test...
error: The following command terminated unexpectedly:
/usr/local/Cellar/zig/0.10.1/bin/zig test /Users/yuri/Documents/schule/maturacpu/movemachine/assembler2/src/main.zig --cache-dir /Users/yuri/Documents/schule/maturacpu/movemachine/assembler2/zig-cache --global-cache-dir /Users/yuri/.cache/zig --name test --enable-cache 
error: the following build command failed with exit code 6:
/Users/yuri/Documents/schule/maturacpu/movemachine/assembler2/zig-cache/o/0c6f026c6e653bb4bee08689f8029211/build /usr/local/Cellar/zig/0.10.1/bin/zig /Users/yuri/Documents/schule/maturacpu/movemachine/assembler2 /Users/yuri/Documents/schule/maturacpu/movemachine/assembler2/zig-cache /Users/yuri/.cache/zig test

it can also be reproduced in main using another allocator, so it isn't just limited to the testing allocator. Try to allocate void results in the same thing

Expected Behavior

The error probably comes from @sizeOf(Enum) being 0. That makes sense, because an enum with just one possibility can be optimized away.

I expect it to at least throw a normal compiler error instead of just crashing. This could be if an enum has less than two possibilities or if we try to allocate a type with a size of 0.

@recursivetree recursivetree added the bug Observed behavior contradicts documented or intended behavior label Apr 23, 2023
@recursivetree
Copy link
Author

recursivetree commented Apr 23, 2023

I just installed a 0.11.0-dev compiler. It seems like the crash is fixed there, but the compiler error is still a bit confusing:

lib/std/mem/Allocator.zig:202:27: error: alignment must be >= 1
) Error![]align(alignment orelse @alignOf(T)) T {
                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~
lib/std/mem.zig:3689:12: error: cast increases pointer alignment
    return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/std/mem.zig:3689:34: note: '[]void' has alignment '0'
    return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
                                 ^~~~~
lib/std/mem.zig:3689:21: note: '[*]u8' has alignment '1'
    return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
                    ^~~~~~~~~~~
lib/std/mem.zig:3689:12: note: consider using '@alignCast'

It contains no reference to where the error originates from

@recursivetree
Copy link
Author

My error, I forgot to insert try. That somehow fundamentally changes the reported error

@mlugg
Copy link
Member

mlugg commented Apr 23, 2023

Allocating zero-bit types ought to work okay, and should essentially just return &.{}. This is actually implemented, but the alignment stuff prematurely breaks it. The fix should be pretty trivial (replace @alignOf(T) with @max(@alignOf(T), 1)).

@recursivetree
Copy link
Author

it is not as trivial as just using @max(@alignOf(T), 1) in the function where it crashes. There are more errors in std.mem that appear when doing it.

I've been wondering whether it even makes sense to have an align of 0. An alignment of 1 mean you can store it in every position, alignment 2 means every second position, etc. But what does alignment 0 mean? Without being an expert at it, types with a size of 0 should work with alignment 1 too.

@Vexu
Copy link
Member

Vexu commented Apr 23, 2023

There is a proposal for changing that #7221

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

3 participants