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...@@ -17092,7 +17092,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
17092 try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy);17092 try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy);
17093 },17093 },
17094 .Enum => {17094 .Enum => {
17095 const struct_val = union_val.val.castTag(.aggregate).?.data;17095 const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
17096 // TODO use reflection instead of magic numbers here17096 // TODO use reflection instead of magic numbers here
17097 // layout: ContainerLayout,17097 // layout: ContainerLayout,
17098 const layout_val = struct_val[0];17098 const layout_val = struct_val[0];
...@@ -17176,7 +17176,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -17176,7 +17176,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
17176 var i: usize = 0;17176 var i: usize = 0;
17177 while (i < fields_len) : (i += 1) {17177 while (i < fields_len) : (i += 1) {
17178 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);17178 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;
17180 // TODO use reflection instead of magic numbers here17180 // TODO use reflection instead of magic numbers here
17181 // name: []const u817181 // name: []const u8
17182 const name_val = field_struct_val[0];17182 const name_val = field_struct_val[0];
...@@ -17189,6 +17189,15 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -17189,6 +17189,15 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
17189 sema.mod,17189 sema.mod,
17190 );17190 );
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
17192 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);17201 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
17193 if (gop.found_existing) {17202 if (gop.found_existing) {
17194 // TODO: better source location17203 // 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'