authorgravatar for inkryption07@gmail.comInKryption <inkryption07@gmail.com> 2022-09-20 21:40:16+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-27 18:38:37+03:00
logc75e8f3616d895d213faad5ad2678d3997f17d8a
treee74ecd06d1967eb671527a7cdea508cc3a22d29e
parentc673e6a48a0adee0385767a431cee815f45df160

Sema: check that reified enum field values fits tag type.


2 files changed, 31 insertions(+), 2 deletions(-)

src/Sema.zig+11-2
......@@ -17092,7 +17092,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1709217092 try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy);
1709317093 },
1709417094 .Enum => {
17095 const struct_val = union_val.val.castTag(.aggregate).?.data;
17095 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
1709617096 // TODO use reflection instead of magic numbers here
1709717097 // layout: ContainerLayout,
1709817098 const layout_val = struct_val[0];
......@@ -17176,7 +17176,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1717617176 var i: usize = 0;
1717717177 while (i < fields_len) : (i += 1) {
1717817178 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
17179 const field_struct_val = elem_val.castTag(.aggregate).?.data;
17179 const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;
1718017180 // TODO use reflection instead of magic numbers here
1718117181 // name: []const u8
1718217182 const name_val = field_struct_val[0];
......@@ -17189,6 +17189,15 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1718917189 sema.mod,
1719017190 );
1719117191
17192 if (!try sema.intFitsInType(block, src, value_val, enum_obj.tag_ty, null)) {
17193 // TODO: better source location
17194 return sema.fail(block, src, "field '{s}' with enumeration value '{}' is too large for backing int type '{}'", .{
17195 field_name,
17196 value_val.fmtValue(Type.@"comptime_int", mod),
17197 enum_obj.tag_ty.fmt(mod),
17198 });
17199 }
17200
1719217201 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
1719317202 if (gop.found_existing) {
1719417203 // TODO: better source location
test/cases/compile_errors/stage2/reified_enum_field_value_overflow.zig created+20
......@@ -0,0 +1,20 @@
1comptime {
2 const E = @Type(.{ .Enum = .{
3 .layout = .Auto,
4 .tag_type = u1,
5 .fields = &.{
6 .{ .name = "f0", .value = 0 },
7 .{ .name = "f1", .value = 1 },
8 .{ .name = "f2", .value = 2 },
9 },
10 .decls = &.{},
11 .is_exhaustive = true,
12 } });
13 _ = E;
14}
15
16// error
17// target=native
18// backend=stage2
19//
20// :2:15: error: field 'f2' with enumeration value '2' is too large for backing int type 'u1'