From f04f867b28211daca38b9c047818fdacc32bc41a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 2 Sep 2026 11:37:17 +0100 Subject: [PATCH] Fix local struct literals losing fields set through `using` --- src/llvm_backend_const.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index b81e6366e..bd15a5346 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -2022,36 +2022,42 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len); } } else if (is_local) { - #if 1 lbProcedure *p = m->curr_procedure; GB_ASSERT(p != nullptr); + + LLVMTypeRef field_llvm_type = lb_type(m, f->type); + + LLVMValueRef ptr = nullptr; if (LLVMIsConstant(values[index])) { lbAddr addr = lb_add_local_generated(p, f->type, false); lb_addr_store(p, addr, lbValue{values[index], f->type}); - values[index] = lb_addr_load(p, addr).value; + ptr = addr.addr.value; + } else { + // a previous field already spilled this member to the stack + GB_ASSERT(LLVMIsALoadInst(values[index])); + ptr = LLVMGetOperand(values[index], 0); } - GB_ASSERT(LLVMIsALoadInst(values[index])); - - LLVMValueRef ptr = LLVMGetOperand(values[index], 0); - - LLVMValueRef *indices = gb_alloc_array(temporary_allocator(), LLVMValueRef, idx_list_len); + LLVMValueRef *indices = gb_alloc_array(temporary_allocator(), LLVMValueRef, idx_list_len+1); LLVMTypeRef lt_u32 = lb_type(m, t_u32); + indices[0] = LLVMConstInt(lt_u32, 0, false); for (unsigned i = 0; i < idx_list_len; i++) { - indices[i] = LLVMConstInt(lt_u32, idx_list[i], false); + indices[i+1] = LLVMConstInt(lt_u32, idx_list[i], false); } - ptr = LLVMBuildGEP2(p->builder, lb_type(m, f->type), ptr, indices, idx_list_len, ""); - ptr = LLVMBuildPointerCast(p->builder, ptr, lb_type(m, alloc_type_pointer(tav.type)), ""); + LLVMValueRef dst = LLVMBuildGEP2(p->builder, field_llvm_type, ptr, indices, idx_list_len+1, ""); + dst = LLVMBuildPointerCast(p->builder, dst, lb_type(m, alloc_type_pointer(tav.type)), ""); if (LLVMIsALoadInst(elem_value)) { i64 sz = type_size_of(tav.type); LLVMValueRef src = LLVMGetOperand(elem_value, 0); - lb_mem_copy_non_overlapping(p, {ptr, t_rawptr}, {src, t_rawptr}, lb_const_int(m, t_int, sz), false); + lb_mem_copy_non_overlapping(p, {dst, t_rawptr}, {src, t_rawptr}, lb_const_int(m, t_int, sz), false); } else { - LLVMBuildStore(p->builder, elem_value, ptr); + LLVMBuildStore(p->builder, elem_value, dst); } - #endif + + values[index] = LLVMBuildLoad2(p->builder, field_llvm_type, ptr, ""); + is_constant = false; } else { is_constant = false;