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 {...@@ -59,12 +59,12 @@ const twords = extern union {
59 s: S,59 s: S,
6060
61 const S = if (native_endian == .Little)61 const S = if (native_endian == .Little)
62 struct {62 extern struct {
63 low: u64,63 low: u64,
64 high: u64,64 high: u64,
65 }65 }
66 else66 else
67 struct {67 extern struct {
68 high: u64,68 high: u64,
69 low: u64,69 low: u64,
70 };70 };
lib/compiler_rt/shift.zig+2-2
...@@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {...@@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
3131
32 all: T,32 all: T,
33 s: if (native_endian == .Little)33 s: if (native_endian == .Little)
34 struct { low: HalfT, high: HalfT }34 extern struct { low: HalfT, high: HalfT }
35 else35 else
36 struct { high: HalfT, low: HalfT },36 extern struct { high: HalfT, low: HalfT },
37 };37 };
38}38}
3939
lib/std/c/haiku.zig+2-2
...@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;...@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
30pub const sem_t = extern struct {30pub const sem_t = extern struct {
31 type: i32,31 type: i32,
32 u: extern union {32 u: extern union {
33 named_sem_id: ?i32,33 named_sem_id: i32,
34 unnamed_sem: ?i32,34 unnamed_sem: i32,
35 },35 },
36 padding: [2]i32,36 padding: [2]i32,
37};37};
src/Sema.zig+4-3
...@@ -18192,6 +18192,7 @@ fn explainWhyTypeIsComptime(...@@ -18192,6 +18192,7 @@ fn explainWhyTypeIsComptime(
18192const ExternPosition = enum {18192const ExternPosition = enum {
18193 ret_ty,18193 ret_ty,
18194 param_ty,18194 param_ty,
18195 union_field,
18195 other,18196 other,
18196};18197};
1819718198
...@@ -18206,9 +18207,9 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr...@@ -18206,9 +18207,9 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
18206 .ErrorUnion,18207 .ErrorUnion,
18207 .ErrorSet,18208 .ErrorSet,
18208 .BoundFn,18209 .BoundFn,
18209 .Void,
18210 .Frame,18210 .Frame,
18211 => return false,18211 => return false,
18212 .Void => return position == .union_field,
18212 .NoReturn => return position == .ret_ty,18213 .NoReturn => return position == .ret_ty,
18213 .Opaque,18214 .Opaque,
18214 .Bool,18215 .Bool,
...@@ -24193,13 +24194,13 @@ fn resolveUnionFully(...@@ -24193,13 +24194,13 @@ fn resolveUnionFully(
24193 for (union_obj.fields.values()) |field| {24194 for (union_obj.fields.values()) |field| {
24194 try sema.resolveTypeFully(block, src, field.ty);24195 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))) {
24197 const msg = msg: {24198 const msg = msg: {
24198 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});24199 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
24199 errdefer msg.destroy(sema.gpa);24200 errdefer msg.destroy(sema.gpa);
2420024201
24201 const src_decl = sema.mod.declPtr(block.src_decl);24202 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
24204 try sema.addDeclaredHereNote(msg, field.ty);24205 try sema.addDeclaredHereNote(msg, field.ty);
24205 break :msg msg;24206 break :msg msg;
test/behavior/union.zig+4-3
...@@ -84,18 +84,19 @@ test "comptime union field access" {...@@ -84,18 +84,19 @@ test "comptime union field access" {
8484
85const FooExtern = extern union {85const FooExtern = extern union {
86 int: i32,86 int: i32,
87 str: struct {87 str: extern struct {
88 slice: []const u8,88 slice: [*:0]const u8,
89 },89 },
90};90};
9191
92test "basic extern unions" {92test "basic extern unions" {
93 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
93 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;94 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9495
95 var foo = FooExtern{ .int = 1 };96 var foo = FooExtern{ .int = 1 };
96 try expect(foo.int == 1);97 try expect(foo.int == 1);
97 foo.str.slice = "Well";98 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"));
99}100}
100101
101const ExternPtrOrInt = extern union {102const ExternPtrOrInt = extern union {