authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-30 17:38:04+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-01 10:22:25+03:00
loge6ebf56dd6cf2e2c23af952d2e9e327703c9cd02
tree5034cb50152f234c3dce7ad746e1f7c7af5fef9c
parentae7b32eb62cb00a09fe2e0e30b307eb83e9f0a86

Sema: validate `@intToEnum` int operand type


10 files changed, 74 insertions(+), 73 deletions(-)

src/Sema.zig+4-3
...@@ -2439,9 +2439,9 @@ fn zirEnumDecl(...@@ -2439,9 +2439,9 @@ fn zirEnumDecl(
2439 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);2439 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
2440 const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);2440 const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);
2441 const msg = msg: {2441 const msg = msg: {
2442 const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});2442 const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name});
2443 errdefer msg.destroy(gpa);2443 errdefer msg.destroy(gpa);
2444 try sema.errNote(block, other_tag_src, msg, "other tag here", .{});2444 try sema.errNote(block, other_tag_src, msg, "other field here", .{});
2445 break :msg msg;2445 break :msg msg;
2446 };2446 };
2447 return sema.failWithOwnedErrorMsg(block, msg);2447 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -2751,7 +2751,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -2751,7 +2751,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
2751 const src = inst_data.src();2751 const src = inst_data.src();
2752 const operand_ty = sema.typeOf(operand);2752 const operand_ty = sema.typeOf(operand);
2753 switch (operand_ty.zigTypeTag()) {2753 switch (operand_ty.zigTypeTag()) {
2754 .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}),2754 .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discardederror is discarded. consider using `try`, `catch`, or `if`", .{}),
2755 else => return,2755 else => return,
2756 }2756 }
2757}2757}
...@@ -6444,6 +6444,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6444,6 +6444,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6444 if (dest_ty.zigTypeTag() != .Enum) {6444 if (dest_ty.zigTypeTag() != .Enum) {
6445 return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});6445 return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
6446 }6446 }
6447 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
64476448
6448 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {6449 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
6449 if (dest_ty.isNonexhaustiveEnum()) {6450 if (dest_ty.isNonexhaustiveEnum()) {
test/cases/compile_errors/discarding_error_value.zig created+12
...@@ -0,0 +1,12 @@
1export fn entry() void {
2 _ = foo();
3}
4fn foo() !void {
5 return error.OutOfMemory;
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :2:12: error: error is discarded. consider using `try`, `catch`, or `if`
test/cases/compile_errors/duplicate_enum_field.zig created+16
...@@ -0,0 +1,16 @@
1const Foo = enum {
2 Bar,
3 Bar,
4};
5
6export fn entry() void {
7 const a: Foo = undefined;
8 _ = a;
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :3:5: error: duplicate enum field 'Bar'
16// :2:5: note: other field here
test/cases/compile_errors/duplicate_error_in_switch.zig created+22
...@@ -0,0 +1,22 @@
1export fn entry() void {
2 foo(452) catch |err| switch (err) {
3 error.Foo => {},
4 error.Bar => {},
5 error.Foo => {},
6 else => {},
7 };
8}
9fn foo(x: i32) !void {
10 switch (x) {
11 0 ... 10 => return error.Foo,
12 11 ... 20 => return error.Bar,
13 else => {},
14 }
15}
16
17// error
18// backend=llvm
19// target=native
20//
21// :5:9: error: duplicate switch value
22// :3:9: note: other value here
test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig created+18
...@@ -0,0 +1,18 @@
1const Small = enum(u2) {
2 One,
3 Two,
4 Three,
5 Four,
6};
7
8export fn entry() void {
9 var y = @as(f32, 3);
10 var x = @intToEnum(Small, y);
11 _ = x;
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :10:31: error: expected integer type, found 'f32'
test/cases/compile_errors/stage1/obj/discarding_error_value.zig deleted-12
...@@ -1,12 +0,0 @@
1export fn entry() void {
2 _ = foo();
3}
4fn foo() !void {
5 return error.OutOfMemory;
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`
test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig deleted-16
...@@ -1,16 +0,0 @@
1const Foo = enum {
2 Bar,
3 Bar,
4};
5
6export fn entry() void {
7 const a: Foo = undefined;
8 _ = a;
9}
10
11// error
12// backend=stage1
13// target=native
14//
15// tmp.zig:3:5: error: duplicate enum field: 'Bar'
16// tmp.zig:2:5: note: other field here
test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig deleted-22
...@@ -1,22 +0,0 @@
1export fn entry() void {
2 foo(452) catch |err| switch (err) {
3 error.Foo => {},
4 error.Bar => {},
5 error.Foo => {},
6 else => {},
7 };
8}
9fn foo(x: i32) !void {
10 switch (x) {
11 0 ... 10 => return error.Foo,
12 11 ... 20 => return error.Bar,
13 else => {},
14 }
15}
16
17// error
18// backend=stage1
19// target=native
20//
21// tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'
22// tmp.zig:3:14: note: other value here
test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig deleted-18
...@@ -1,18 +0,0 @@
1const Small = enum(u2) {
2 One,
3 Two,
4 Three,
5 Four,
6};
7
8export fn entry() void {
9 var y = @as(f32, 3);
10 var x = @intToEnum(Small, y);
11 _ = x;
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:10:31: error: expected integer type, found 'f32'
test/stage2/cbe.zig+2-2
...@@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void {
729 \\ _ = E1.a;729 \\ _ = E1.a;
730 \\}730 \\}
731 , &.{731 , &.{
732 ":1:28: error: duplicate enum tag",732 ":1:28: error: duplicate enum field 'b'",
733 ":1:22: note: other tag here",733 ":1:22: note: other field here",
734 });734 });
735735
736 case.addError(736 case.addError(