Commit e903b00eec

Tadeo Kondrak <me@tadeo.ca>
2020-09-29 22:01:20
stage1: Fix @Type(.Enum) with invalid tag_type
Fixes https://github.com/ziglang/zig/issues/6459
1 parent fe117d9
Changed files (2)
src
stage1
test
src/stage1/ir.cpp
@@ -26150,6 +26150,13 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
             ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
 
             ZigType *tag_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "tag_type", 1);
+            if (type_is_invalid(tag_type))
+                return ira->codegen->invalid_inst_gen->value->type;
+            if (tag_type->id != ZigTypeIdInt) {
+                ir_add_error(ira, source_instr, buf_sprintf(
+                    "TypeInfo.Enum.tag_type must be an integer type, not '%s'", buf_ptr(&tag_type->name)));
+                return ira->codegen->invalid_inst_gen->value->type;
+            }
 
             ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 2);
             if (fields_value == nullptr)
test/compile_errors.zig
@@ -2,6 +2,42 @@ const tests = @import("tests.zig");
 const std = @import("std");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add("@Type for exhaustive enum with undefined tag type",
+        \\const TypeInfo = @import("builtin").TypeInfo;
+        \\const Tag = @Type(.{
+        \\    .Enum = .{
+        \\        .layout = .Auto,
+        \\        .tag_type = undefined,
+        \\        .fields = &[_]TypeInfo.EnumField{},
+        \\        .decls = &[_]TypeInfo.Declaration{},
+        \\        .is_exhaustive = false,
+        \\    },
+        \\});
+        \\export fn entry() void {
+        \\    _ = @intToEnum(Tag, 0);
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:2:20: error: use of undefined value here causes undefined behavior",
+    });
+
+    cases.add("@Type for exhaustive enum with non-integer tag type",
+        \\const TypeInfo = @import("builtin").TypeInfo;
+        \\const Tag = @Type(.{
+        \\    .Enum = .{
+        \\        .layout = .Auto,
+        \\        .tag_type = bool,
+        \\        .fields = &[_]TypeInfo.EnumField{},
+        \\        .decls = &[_]TypeInfo.Declaration{},
+        \\        .is_exhaustive = false,
+        \\    },
+        \\});
+        \\export fn entry() void {
+        \\    _ = @intToEnum(Tag, 0);
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",
+    });
+
     cases.add("slice sentinel mismatch",
         \\export fn entry() void {
         \\    const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };