authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-03 22:18:05-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-03 22:18:05-07:00
log314ce5465dfdc9f4d1e2d178704b47666d541fc4
tree6b2d299575d87f405170c74b44fb99e279254a99
parent5735ce39ae5a9fb2bc2ac9f5a722276c291b28bc

std: better definition for std.os.linux.epoll_event

The previous definition depends on a non-lang-spec-compliant memory layout for packed structs, which happens to trigger #11989 in stage2. This commit changes the struct to be an extern struct with an align(4) field. However, stage1 cannot handle this, so conditional compilation logic is used to select different struct definitions depending on stage1 vs stage2. This works around #11989 but does not solve the underlying problem - putting an extern union inside a packed struct will still trigger the assert. After this, both stage1 and stage2 std lib tests run assertion-clean with a debug LLVM 13.

1 files changed, 12 insertions(+), 7 deletions(-)

lib/std/os/linux.zig+12-7
......@@ -3222,16 +3222,21 @@ pub const epoll_data = extern union {
32223222 @"u64": u64,
32233223};
32243224
3225// On x86_64 the structure is packed so that it matches the definition of its
3226// 32bit counterpart
3227pub const epoll_event = switch (native_arch) {
3228 .x86_64 => packed struct {
3229 events: u32,
3230 data: epoll_data,
3225pub const epoll_event = switch (builtin.zig_backend) {
3226 // stage1 crashes with the align(4) field so we have this workaround
3227 .stage1 => switch (native_arch) {
3228 .x86_64 => packed struct {
3229 events: u32,
3230 data: epoll_data,
3231 },
3232 else => extern struct {
3233 events: u32,
3234 data: epoll_data,
3235 },
32313236 },
32323237 else => extern struct {
32333238 events: u32,
3234 data: epoll_data,
3239 data: epoll_data align(4),
32353240 },
32363241};
32373242