authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-11 19:57:41+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-11 20:30:16+03:00
log122c76a1670e4b925ccdabaa771f59e5df6d43aa
tree3649a70bb7e967af3818d64c250e413a04c107f7
parentd00da05ecbeca36e8ca25dcb1238bf98b38081a5

Sema: allow `void` as an extern union field & fix invalid extern unions


5 files changed, 14 insertions(+), 12 deletions(-)

lib/compiler_rt/multi3.zig+2-2
......@@ -59,12 +59,12 @@ const twords = extern union {
5959 s: S,
6060
6161 const S = if (native_endian == .Little)
62 struct {
62 extern struct {
6363 low: u64,
6464 high: u64,
6565 }
6666 else
67 struct {
67 extern struct {
6868 high: u64,
6969 low: u64,
7070 };
lib/compiler_rt/shift.zig+2-2
......@@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
3131
3232 all: T,
3333 s: if (native_endian == .Little)
34 struct { low: HalfT, high: HalfT }
34 extern struct { low: HalfT, high: HalfT }
3535 else
36 struct { high: HalfT, low: HalfT },
36 extern struct { high: HalfT, low: HalfT },
3737 };
3838}
3939
lib/std/c/haiku.zig+2-2
......@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
3030pub const sem_t = extern struct {
3131 type: i32,
3232 u: extern union {
33 named_sem_id: ?i32,
34 unnamed_sem: ?i32,
33 named_sem_id: i32,
34 unnamed_sem: i32,
3535 },
3636 padding: [2]i32,
3737};
src/Sema.zig+4-3
......@@ -18192,6 +18192,7 @@ fn explainWhyTypeIsComptime(
1819218192const ExternPosition = enum {
1819318193 ret_ty,
1819418194 param_ty,
18195 union_field,
1819518196 other,
1819618197};
1819718198
......@@ -18206,9 +18207,9 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
1820618207 .ErrorUnion,
1820718208 .ErrorSet,
1820818209 .BoundFn,
18209 .Void,
1821018210 .Frame,
1821118211 => return false,
18212 .Void => return position == .union_field,
1821218213 .NoReturn => return position == .ret_ty,
1821318214 .Opaque,
1821418215 .Bool,
......@@ -24193,13 +24194,13 @@ fn resolveUnionFully(
2419324194 for (union_obj.fields.values()) |field| {
2419424195 try sema.resolveTypeFully(block, src, field.ty);
2419524196
24196 if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
24197 if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) {
2419724198 const msg = msg: {
2419824199 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
2419924200 errdefer msg.destroy(sema.gpa);
2420024201
2420124202 const src_decl = sema.mod.declPtr(block.src_decl);
24202 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other);
24203 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field);
2420324204
2420424205 try sema.addDeclaredHereNote(msg, field.ty);
2420524206 break :msg msg;
test/behavior/union.zig+4-3
......@@ -84,18 +84,19 @@ test "comptime union field access" {
8484
8585const FooExtern = extern union {
8686 int: i32,
87 str: struct {
88 slice: []const u8,
87 str: extern struct {
88 slice: [*:0]const u8,
8989 },
9090};
9191
9292test "basic extern unions" {
93 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9394 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9495
9596 var foo = FooExtern{ .int = 1 };
9697 try expect(foo.int == 1);
9798 foo.str.slice = "Well";
98 try expect(std.mem.eql(u8, foo.str.slice, "Well"));
99 try expect(std.mem.eql(u8, std.mem.sliceTo(foo.str.slice, 0), "Well"));
99100}
100101
101102const ExternPtrOrInt = extern union {