zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit a9cdacff95a2a6f60945c7b2a299f9f66bd94ddb (tree)
parent 7a51e0befe12c9d17e39f736027a205b1f19bdc6
Author: Veikka Tuominen <git@vexu.eu>
Date:   Fri,  2 Sep 2022 15:31:01 +0300

Sema: add error for enum tag value overflow

Closes #12291

Diffstat:
Msrc/Sema.zig | 16++++++++++++++++
Atest/cases/compile_errors/overflow_in_enum_value_allocation.zig | 14++++++++++++++
Atest/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig | 18++++++++++++++++++
Dtest/cases/compile_errors/stage1/obj/overflow_in_enum_value_allocation.zig | 14--------------
Dtest/cases/compile_errors/stage1/obj/specify_enum_tag_type_that_is_too_small.zig | 18------------------
5 files changed, 48 insertions(+), 32 deletions(-)

diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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'