diff --git a/releasenotes.md b/releasenotes.md index 7a503a053..5ece4d41d 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -39,6 +39,7 @@ - Alias and distinct types didn't check the underlying type wasn't compile time or optional. - Incorrect nameof on nested struct names. #2492 - Issue not correctly aborting compilation on recursive generics. +- Crash during codegen when taking the typeid of an empty enum with associated values. ### Stdlib changes - Added generic `InterfaceList` to store a list of values that implement a specific interface diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 747d131cd..b94805bfb 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -557,6 +557,7 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type) if (val_type != LLVMTypeOf(llvm_value)) mixed = true; } Decl *associated_value = associated_values[ai]; + if (!val_type)val_type = llvm_get_type(c, associated_value->type); LLVMValueRef associated_value_arr = mixed ? llvm_get_packed_struct(c, values, elements) : llvm_get_array(val_type, values, elements); scratch_buffer_set_extern_decl_name(decl, true); diff --git a/test/test_suite/enumerations/enum_empty_typeid.c3t b/test/test_suite/enumerations/enum_empty_typeid.c3t new file mode 100644 index 000000000..0a2953868 --- /dev/null +++ b/test/test_suite/enumerations/enum_empty_typeid.c3t @@ -0,0 +1,27 @@ +// #target: macos-x64 +module test; + +enum No_Els_Assoc : (any anything) +{} + +macro typeid @segfault () => No_Els_Assoc.typeid; + +fn int main () +{ + typeid x = @segfault(); + return 0; +} + +/* #expect: test.ll + +@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.No_Els_Assoc" = linkonce global { i8, i64, ptr, i64, i64, i64, [0 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 0, [0 x %"char[]"] zeroinitializer }, align 8 +@"test.No_Els_Assoc$anything" = linkonce constant [0 x %any] zeroinitializer, align 8 + +; Function Attrs: nounwind uwtable +define i32 @main() #0 { +entry: + %x = alloca i64, align 8 + store i64 ptrtoint (ptr @"$ct.test.No_Els_Assoc" to i64), ptr %x, align 8 + ret i32 0 +}