Prevent crash with empty non-exhaustive enum

This commit is contained in:
LemonBoy 2020-01-18 15:13:21 +01:00
parent b72f858194
commit c53d94e512
3 changed files with 22 additions and 2 deletions

View File

@ -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; 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); ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
for (uint32_t i = 0; i < field_count; i += 1) { for (uint32_t i = 0; i < field_count; i += 1) {

View File

@ -21631,7 +21631,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
case ZigTypeIdEnum: { case ZigTypeIdEnum: {
if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction; 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]; TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type);
bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value);

View File

@ -65,6 +65,26 @@ test "non-exhaustive enum" {
comptime S.doTheTest(52); 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" { test "enum type" {
const foo1 = Foo{ .One = 13 }; const foo1 = Foo{ .One = 13 };
const foo2 = Foo{ const foo2 = Foo{