diff --git a/src/Sema.zig b/src/Sema.zig index a49aec871bb18a88f2d343a28a9b96d558c16566..1ee5bf71b1fa740b477b3609fb23bd8a5a7fdc1d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2586,6 +2586,7 @@ fn zirEnumDecl( var cur_bit_bag: u32 = undefined; var field_i: u32 = 0; var last_tag_val: ?Value = null; + var tag_val_buf: Value.Payload.U64 = undefined; while (field_i < fields_len) : (field_i += 1) { if (field_i % 32 == 0) { cur_bit_bag = sema.code.extra[bit_bag_index]; @@ -2641,6 +2642,21 @@ fn zirEnumDecl( .ty = enum_obj.tag_ty, .mod = mod, }); + } else { + tag_val_buf = .{ + .base = .{ .tag = .int_u64 }, + .data = field_i, + }; + last_tag_val = Value.initPayload(&tag_val_buf.base); + } + + if (!(try sema.intFitsInType(block, src, last_tag_val.?, enum_obj.tag_ty, null))) { + const tree = try sema.getAstTree(block); + const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); + const msg = try sema.errMsg(block, field_src, "enumeration value '{}' too large for type '{}'", .{ + last_tag_val.?.fmtValue(enum_obj.tag_ty, mod), enum_obj.tag_ty.fmt(mod), + }); + return sema.failWithOwnedErrorMsg(msg); } } return decl_val; diff --git a/test/cases/compile_errors/overflow_in_enum_value_allocation.zig b/test/cases/compile_errors/overflow_in_enum_value_allocation.zig new file mode 100644 index 0000000000000000000000000000000000000000..2a5b55e86da148eb88a78eab5ba1bdc537a40e16 --- /dev/null +++ b/test/cases/compile_errors/overflow_in_enum_value_allocation.zig @@ -0,0 +1,14 @@ +const Moo = enum(u8) { + Last = 255, + Over, +}; +pub export fn entry() void { + var y = Moo.Last; + _ = y; +} + +// error +// backend=stage2 +// target=native +// +// :3:5: error: enumeration value '256' too large for type 'u8' diff --git a/test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig b/test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig new file mode 100644 index 0000000000000000000000000000000000000000..d878bec18b0dac8a482d3044d4a4f1d5391775b6 --- /dev/null +++ b/test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig @@ -0,0 +1,18 @@ +const Small = enum (u2) { + One, + Two, + Three, + Four, + Five, +}; + +export fn entry() void { + var x = Small.One; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :6:5: error: enumeration value '4' too large for type 'u2' diff --git a/test/cases/compile_errors/stage1/obj/overflow_in_enum_value_allocation.zig b/test/cases/compile_errors/stage1/obj/overflow_in_enum_value_allocation.zig deleted file mode 100644 index c5dc5c1dcf8f697da9504f335a5da40150a4fbc1..0000000000000000000000000000000000000000 --- a/test/cases/compile_errors/stage1/obj/overflow_in_enum_value_allocation.zig +++ /dev/null @@ -1,14 +0,0 @@ -const Moo = enum(u8) { - Last = 255, - Over, -}; -pub fn main() void { - var y = Moo.Last; - _ = y; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:5: error: enumeration value 256 too large for type 'u8' diff --git a/test/cases/compile_errors/stage1/obj/specify_enum_tag_type_that_is_too_small.zig b/test/cases/compile_errors/stage1/obj/specify_enum_tag_type_that_is_too_small.zig deleted file mode 100644 index dc7077c8f84d0f1b21aabc89d896b3737aad7a79..0000000000000000000000000000000000000000 --- a/test/cases/compile_errors/stage1/obj/specify_enum_tag_type_that_is_too_small.zig +++ /dev/null @@ -1,18 +0,0 @@ -const Small = enum (u2) { - One, - Two, - Three, - Four, - Five, -}; - -export fn entry() void { - var x = Small.One; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'