authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 15:31:01+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 17:57:11+03:00
loga9cdacff95a2a6f60945c7b2a299f9f66bd94ddb
treef2d874e374a192e79a359d62ccf1585bfc09463a
parent7a51e0befe12c9d17e39f736027a205b1f19bdc6

Sema: add error for enum tag value overflow

Closes #12291

5 files changed, 48 insertions(+), 32 deletions(-)

src/Sema.zig+16
...@@ -2586,6 +2586,7 @@ fn zirEnumDecl(...@@ -2586,6 +2586,7 @@ fn zirEnumDecl(
2586 var cur_bit_bag: u32 = undefined;2586 var cur_bit_bag: u32 = undefined;
2587 var field_i: u32 = 0;2587 var field_i: u32 = 0;
2588 var last_tag_val: ?Value = null;2588 var last_tag_val: ?Value = null;
2589 var tag_val_buf: Value.Payload.U64 = undefined;
2589 while (field_i < fields_len) : (field_i += 1) {2590 while (field_i < fields_len) : (field_i += 1) {
2590 if (field_i % 32 == 0) {2591 if (field_i % 32 == 0) {
2591 cur_bit_bag = sema.code.extra[bit_bag_index];2592 cur_bit_bag = sema.code.extra[bit_bag_index];
...@@ -2641,6 +2642,21 @@ fn zirEnumDecl(...@@ -2641,6 +2642,21 @@ fn zirEnumDecl(
2641 .ty = enum_obj.tag_ty,2642 .ty = enum_obj.tag_ty,
2642 .mod = mod,2643 .mod = mod,
2643 });2644 });
2645 } else {
2646 tag_val_buf = .{
2647 .base = .{ .tag = .int_u64 },
2648 .data = field_i,
2649 };
2650 last_tag_val = Value.initPayload(&tag_val_buf.base);
2651 }
2652
2653 if (!(try sema.intFitsInType(block, src, last_tag_val.?, enum_obj.tag_ty, null))) {
2654 const tree = try sema.getAstTree(block);
2655 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
2656 const msg = try sema.errMsg(block, field_src, "enumeration value '{}' too large for type '{}'", .{
2657 last_tag_val.?.fmtValue(enum_obj.tag_ty, mod), enum_obj.tag_ty.fmt(mod),
2658 });
2659 return sema.failWithOwnedErrorMsg(msg);
2644 }2660 }
2645 }2661 }
2646 return decl_val;2662 return decl_val;
test/cases/compile_errors/overflow_in_enum_value_allocation.zig created+14
...@@ -0,0 +1,14 @@
1const Moo = enum(u8) {
2 Last = 255,
3 Over,
4};
5pub export fn entry() void {
6 var y = Moo.Last;
7 _ = y;
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :3:5: error: enumeration value '256' too large for type 'u8'
test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig created+18
...@@ -0,0 +1,18 @@
1const Small = enum (u2) {
2 One,
3 Two,
4 Three,
5 Four,
6 Five,
7};
8
9export fn entry() void {
10 var x = Small.One;
11 _ = x;
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :6:5: error: enumeration value '4' too large for type 'u2'
test/cases/compile_errors/stage1/obj/overflow_in_enum_value_allocation.zig deleted-14
...@@ -1,14 +0,0 @@
1const Moo = enum(u8) {
2 Last = 255,
3 Over,
4};
5pub fn main() void {
6 var y = Moo.Last;
7 _ = y;
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'
test/cases/compile_errors/stage1/obj/specify_enum_tag_type_that_is_too_small.zig deleted-18
...@@ -1,18 +0,0 @@
1const Small = enum (u2) {
2 One,
3 Two,
4 Three,
5 Four,
6 Five,
7};
8
9export fn entry() void {
10 var x = Small.One;
11 _ = x;
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'