From cd4fd02ee3a355989c2e0ebed104933bbddc78c4 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 31 Oct 2024 21:27:46 +0100 Subject: [PATCH] Sometimes generating introspection info would not be in the global scope causing a crash #1586. --- releasenotes.md | 1 + src/compiler/llvm_codegen_type.c | 18 ++++++++++++++ .../enumerations/introspection_data_error.c3t | 24 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 test/test_suite/enumerations/introspection_data_error.c3t diff --git a/releasenotes.md b/releasenotes.md index bdcc10411..cc071f33f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -53,6 +53,7 @@ - Named vector component access would not fold at compile time. #1574 - `$define` would occasionally not properly evaluate declarations it encountered. - Fixes with error handling recursive `@tag` #1583. +- Sometimes generating introspection info would not be in the global scope causing a crash #1586. ### Stdlib changes - Remove unintended print of `char[]` as String diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index fa5b17d5d..20a43105d 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -420,6 +420,10 @@ static inline LLVMValueRef llvm_generate_temp_introspection_global(GenContext *c static inline LLVMValueRef llvm_generate_introspection_global(GenContext *c, LLVMValueRef original_global, Type *type, IntrospectType introspect_type, Type *inner, size_t len, LLVMValueRef additional, bool is_external) { + // Push the builder + void *builder = c->builder; + c->builder = c->global_builder; + if (original_global) { assert(type->backend_typeid); @@ -478,6 +482,7 @@ static inline LLVMValueRef llvm_generate_introspection_global(GenContext *c, LLV { type->backend_typeid = LLVMBuildPtrToInt(c->builder, global_name, c->typeid_type, ""); } + c->builder = builder; return type->backend_typeid; } static LLVMValueRef llvm_get_introspection_for_builtin_type(GenContext *c, Type *type, IntrospectType introspect_type, int bits) @@ -488,6 +493,10 @@ static LLVMValueRef llvm_get_introspection_for_builtin_type(GenContext *c, Type static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type) { + + void *builder = c->builder; + c->builder = c->global_builder; + Decl *decl = type->decl; bool is_external = decl->unit->module != c->code_module; bool is_dynamic = decl->is_dynamic; @@ -563,11 +572,15 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type) LLVMSetGlobalConstant(global_ref, true); associated_value->backend_ref = global_ref; } + c->builder = builder; return val; } static LLVMValueRef llvm_get_introspection_for_struct_union(GenContext *c, Type *type) { + void *builder = c->builder; + c->builder = c->global_builder; + Decl *decl = type->decl; Decl **decls = decl->strukt.members; LLVMValueRef ref = llvm_generate_temp_introspection_global(c, type); @@ -579,6 +592,7 @@ static LLVMValueRef llvm_get_introspection_for_struct_union(GenContext *c, Type } } + c->builder = builder; return llvm_generate_introspection_global(c, ref, type, decl->decl_kind == DECL_UNION ? INTROSPECT_TYPE_UNION : INTROSPECT_TYPE_STRUCT, NULL, vec_size(decls), NULL, false); @@ -586,6 +600,9 @@ static LLVMValueRef llvm_get_introspection_for_struct_union(GenContext *c, Type static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type) { + void *builder = c->builder; + c->builder = c->global_builder; + Decl *decl = type->decl; Decl **fault_vals = decl->enums.values; unsigned elements = vec_size(fault_vals); @@ -613,6 +630,7 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type) { values[i] = fault_vals[i]->backend_ref; } + c->builder = builder; return llvm_generate_introspection_global(c, ref, type, INTROSPECT_TYPE_FAULT, NULL, elements, NULL, false); } diff --git a/test/test_suite/enumerations/introspection_data_error.c3t b/test/test_suite/enumerations/introspection_data_error.c3t new file mode 100644 index 000000000..6b4ea1649 --- /dev/null +++ b/test/test_suite/enumerations/introspection_data_error.c3t @@ -0,0 +1,24 @@ +// #target: macos-x64 +module boom; +enum Boom: int (String a) { + BOOM = {0} +} + +module app; +import std::io, boom; +fn void! main(String[] args) { + io::printn(Boom.BOOM); +} +/* #expect: boom.ll + + + + +---------------------------------------------------> boom.ll + +@.enum.BOOM = internal constant [5 x i8] c"BOOM\00", align 1 +@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.boom.Boom" = linkonce global { i8, i64, ptr, i64, i64, i64, [1 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 1, [1 x %"char[]"] [%"char[]" { ptr @.enum.BOOM, i64 4 }] }, align 8 +@.__const_slice = private unnamed_addr global [1 x i8] zeroinitializer, align 1 +@"boom.Boom$a" = linkonce constant [1 x %"char[]"] [%"char[]" { ptr @.__const_slice, i64 1 }], align 8 +