commit e6ebf56dd6cf2e2c23af952d2e9e327703c9cd02 (tree)
parent ae7b32eb62cb00a09fe2e0e30b307eb83e9f0a86
Author: Veikka Tuominen <git@vexu.eu>
Date: Thu, 30 Jun 2022 17:38:04 +0300
Sema: validate `@intToEnum` int operand type
Diffstat:
10 files changed, 74 insertions(+), 73 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -2439,9 +2439,9 @@ fn zirEnumDecl(
const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);
const msg = msg: {
- const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});
+ const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name});
errdefer msg.destroy(gpa);
- try sema.errNote(block, other_tag_src, msg, "other tag here", .{});
+ try sema.errNote(block, other_tag_src, msg, "other field here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2751,7 +2751,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
const src = inst_data.src();
const operand_ty = sema.typeOf(operand);
switch (operand_ty.zigTypeTag()) {
- .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}),
+ .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discardederror is discarded. consider using `try`, `catch`, or `if`", .{}),
else => return,
}
}
@@ -6444,6 +6444,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
if (dest_ty.zigTypeTag() != .Enum) {
return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
}
+ _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
if (dest_ty.isNonexhaustiveEnum()) {
diff --git a/test/cases/compile_errors/discarding_error_value.zig b/test/cases/compile_errors/discarding_error_value.zig
@@ -0,0 +1,12 @@
+export fn entry() void {
+ _ = foo();
+}
+fn foo() !void {
+ return error.OutOfMemory;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:12: error: error is discarded. consider using `try`, `catch`, or `if`
diff --git a/test/cases/compile_errors/duplicate_enum_field.zig b/test/cases/compile_errors/duplicate_enum_field.zig
@@ -0,0 +1,16 @@
+const Foo = enum {
+ Bar,
+ Bar,
+};
+
+export fn entry() void {
+ const a: Foo = undefined;
+ _ = a;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :3:5: error: duplicate enum field 'Bar'
+// :2:5: note: other field here
diff --git a/test/cases/compile_errors/duplicate_error_in_switch.zig b/test/cases/compile_errors/duplicate_error_in_switch.zig
@@ -0,0 +1,22 @@
+export fn entry() void {
+ foo(452) catch |err| switch (err) {
+ error.Foo => {},
+ error.Bar => {},
+ error.Foo => {},
+ else => {},
+ };
+}
+fn foo(x: i32) !void {
+ switch (x) {
+ 0 ... 10 => return error.Foo,
+ 11 ... 20 => return error.Bar,
+ else => {},
+ }
+}
+
+// error
+// backend=llvm
+// target=native
+//
+// :5:9: error: duplicate switch value
+// :3:9: note: other value here
diff --git a/test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig b/test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig
@@ -0,0 +1,18 @@
+const Small = enum(u2) {
+ One,
+ Two,
+ Three,
+ Four,
+};
+
+export fn entry() void {
+ var y = @as(f32, 3);
+ var x = @intToEnum(Small, y);
+ _ = x;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :10:31: error: expected integer type, found 'f32'
diff --git a/test/cases/compile_errors/stage1/obj/discarding_error_value.zig b/test/cases/compile_errors/stage1/obj/discarding_error_value.zig
@@ -1,12 +0,0 @@
-export fn entry() void {
- _ = foo();
-}
-fn foo() !void {
- return error.OutOfMemory;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`
diff --git a/test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig b/test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig
@@ -1,16 +0,0 @@
-const Foo = enum {
- Bar,
- Bar,
-};
-
-export fn entry() void {
- const a: Foo = undefined;
- _ = a;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:3:5: error: duplicate enum field: 'Bar'
-// tmp.zig:2:5: note: other field here
diff --git a/test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig b/test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig
@@ -1,22 +0,0 @@
-export fn entry() void {
- foo(452) catch |err| switch (err) {
- error.Foo => {},
- error.Bar => {},
- error.Foo => {},
- else => {},
- };
-}
-fn foo(x: i32) !void {
- switch (x) {
- 0 ... 10 => return error.Foo,
- 11 ... 20 => return error.Bar,
- else => {},
- }
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'
-// tmp.zig:3:14: note: other value here
diff --git a/test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig b/test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig
@@ -1,18 +0,0 @@
-const Small = enum(u2) {
- One,
- Two,
- Three,
- Four,
-};
-
-export fn entry() void {
- var y = @as(f32, 3);
- var x = @intToEnum(Small, y);
- _ = x;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:10:31: error: expected integer type, found 'f32'
diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig
@@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void {
\\ _ = E1.a;
\\}
, &.{
- ":1:28: error: duplicate enum tag",
- ":1:22: note: other tag here",
+ ":1:28: error: duplicate enum field 'b'",
+ ":1:22: note: other field here",
});
case.addError(