authorgravatar for kkhaike@gmail.comkkHAIKE <kkhaike@gmail.com> 2022-09-27 18:23:51+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-09-27 13:23:51+03:00
logba5cbea0c3c6ee2e22606365edde18342fcf0579
tree1c3f9c6581391abd525ac54bf55b40ccc8fcfe1a
parentf7f15e99c418ab0efac268e9087ce45d55744edc
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Sema: fix segfault when union init with empty field


2 files changed, 47 insertions(+), 3 deletions(-)

src/Sema.zig+10-3
...@@ -15885,6 +15885,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -15885,6 +15885,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
15885 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),15885 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),
15886 .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty),15886 .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty),
15887 .Void => return sema.addConstant(obj_ty, Value.void),15887 .Void => return sema.addConstant(obj_ty, Value.void),
15888 .Union => return sema.fail(block, src, "union initializer must initialize one field", .{}),
15888 else => return sema.failWithArrayInitNotSupported(block, src, obj_ty),15889 else => return sema.failWithArrayInitNotSupported(block, src, obj_ty),
15889 }15890 }
15890}15891}
...@@ -25854,14 +25855,19 @@ fn coerceAnonStructToUnion(...@@ -25854,14 +25855,19 @@ fn coerceAnonStructToUnion(
25854 inst_src: LazySrcLoc,25855 inst_src: LazySrcLoc,
25855) !Air.Inst.Ref {25856) !Air.Inst.Ref {
25856 const inst_ty = sema.typeOf(inst);25857 const inst_ty = sema.typeOf(inst);
25857 const anon_struct = inst_ty.castTag(.anon_struct).?.data;25858 const field_count = inst_ty.structFieldCount();
25858 if (anon_struct.types.len != 1) {25859 if (field_count != 1) {
25859 const msg = msg: {25860 const msg = msg: {
25860 const msg = try sema.errMsg(25861 const msg = if (field_count > 1) try sema.errMsg(
25861 block,25862 block,
25862 inst_src,25863 inst_src,
25863 "cannot initialize multiple union fields at once, unions can only have one active field",25864 "cannot initialize multiple union fields at once, unions can only have one active field",
25864 .{},25865 .{},
25866 ) else try sema.errMsg(
25867 block,
25868 inst_src,
25869 "union initializer must initialize one field",
25870 .{},
25865 );25871 );
25866 errdefer msg.destroy(sema.gpa);25872 errdefer msg.destroy(sema.gpa);
2586725873
...@@ -25874,6 +25880,7 @@ fn coerceAnonStructToUnion(...@@ -25874,6 +25880,7 @@ fn coerceAnonStructToUnion(
25874 return sema.failWithOwnedErrorMsg(msg);25880 return sema.failWithOwnedErrorMsg(msg);
25875 }25881 }
2587625882
25883 const anon_struct = inst_ty.castTag(.anon_struct).?.data;
25877 const field_name = anon_struct.names[0];25884 const field_name = anon_struct.names[0];
25878 const init = try sema.structFieldVal(block, inst_src, inst, field_name, inst_src, inst_ty);25885 const init = try sema.structFieldVal(block, inst_src, inst, field_name, inst_src, inst_ty);
25879 return sema.unionInit(block, init, inst_src, union_ty, union_ty_src, field_name, inst_src);25886 return sema.unionInit(block, init, inst_src, union_ty, union_ty_src, field_name, inst_src);
test/cases/compile_errors/union_init_with_none_or_multiple_fields.zig created+37
...@@ -0,0 +1,37 @@
1const U1 = union {
2 a: u8,
3 b: i8,
4};
5const U2 = union(enum) {
6 a: u8,
7 b: i8,
8};
9export fn u1z() void {
10 const x: U1 = .{};
11 _ = x;
12}
13export fn u1m() void {
14 const x: U1 = .{ .a = 1, .b = 1 };
15 _ = x;
16}
17export fn u2z() void {
18 const x: U2 = U2{};
19 _ = x;
20}
21export fn u2m() void {
22 const x: U2 = .{ .a = 1, .b = 1 };
23 _ = x;
24}
25
26// error
27// backend=stage2
28// target=native
29//
30// :9:1: error: union initializer must initialize one field
31// :14:20: error: cannot initialize multiple union fields at once, unions can only have one active field
32// :14:31: note: additional initializer here
33// :18:21: error: union initializer must initialize one field
34// :22:20: error: cannot initialize multiple union fields at once, unions can only have one active field
35// :22:31: note: additional initializer here
36// :1:12: note: union declared here
37// :5:12: note: union declared here