Commit c53d94e512

LemonBoy <thatlemon@gmail.com>
2020-01-18 15:13:21
Prevent crash with empty non-exhaustive enum
1 parent b72f858
Changed files (3)
src
test
stage1
behavior
src/analyze.cpp
@@ -8312,7 +8312,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
 
     uint32_t field_count = enum_type->data.enumeration.src_field_count;
 
-    assert(enum_type->data.enumeration.fields);
+    assert(field_count == 0 || enum_type->data.enumeration.fields != nullptr);
     ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
 
     for (uint32_t i = 0; i < field_count; i += 1) {
src/ir.cpp
@@ -21631,7 +21631,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
         case ZigTypeIdEnum: {
             if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown)))
                 return ira->codegen->invalid_instruction;
-            if (target_type->data.enumeration.src_field_count < 2) {
+            if (target_type->data.enumeration.src_field_count == 1) {
                 TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
                 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type);
                 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value);
test/stage1/behavior/enum.zig
@@ -65,6 +65,26 @@ test "non-exhaustive enum" {
     comptime S.doTheTest(52);
 }
 
+test "empty non-exhaustive enum" {
+    const S = struct {
+        const E = enum(u8) {
+            _,
+        };
+        fn doTheTest(y: u8) void {
+            var e = @intToEnum(E, y);
+            expect(switch (e) {
+                _ => true,
+            });
+            expect(@enumToInt(e) == y);
+
+            expect(@typeInfo(E).Enum.fields.len == 0);
+            expect(@typeInfo(E).Enum.is_exhaustive == false);
+        }
+    };
+    S.doTheTest(42);
+    comptime S.doTheTest(42);
+}
+
 test "enum type" {
     const foo1 = Foo{ .One = 13 };
     const foo2 = Foo{