ziglang / zig

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

Zero-bit types allowed in too many extern positions #21401

Open wooster0 opened 1 month ago

wooster0 commented 1 month ago

Zig Version

0.14.0-dev.1511+54b668f8a

Steps to Reproduce and Observed Behavior

extern const a: u0;

export fn x() void {
    var b: u0 = 0;
    @atomicStore(u0, &b, a, .unordered);
}
$ zig build-lib x.zig
error: Bitwidth for integer type out of range (Producer: 'zig 0.14.0' Reader: 'LLVM 18.1.8')

Expected Behavior

A successful compilation.

alexrp commented 1 month ago

Wonder why this check (apparently?) isn't working:

https://github.com/ziglang/zig/blob/b56a667ecdb9f34dbd60d247d4237bc008755979/src/codegen/llvm.zig#L9902

Aside: Doing nothing at all for the zero-sized case is very surprising behavior IMO. I would expect the instruction to at least result in a fence corresponding to the given ordering, even if no store actually takes place; the fence has implications for code other than the store itself. (And likewise for atomic loads.)

Vexu commented 1 month ago

The problem is not with that check but with this one: https://github.com/ziglang/zig/blob/4d81e8ee915c3e012131cf90ed87cc8c6a01a934/src/Sema.zig#L27601

Using u1 gives the expected error:

a.zig:1:17: error: extern variable cannot have type 'u1'
extern const a: u1;
                ^~
a.zig:1:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible
referenced by:
    x: a.zig:4:17
    x: a.zig:3:1
    4 reference(s) hidden; use '-freference-trace=6' to see all references
Vexu commented 1 month ago

Regressed in #16404, fix is to check the position.