| author | |
| committer | |
| log | 9050cd847a2a767df34bc3e0bbc9c789b8a49a91 |
| tree | 297aa589cd56f83773336b359519879e8c001f6e |
| parent | 7495fd8cb9eea3d571ec62eff069b443ac0e3a6a |
| signature |
...passed as generic fn parameter causing invalid LLVM IR.
closes #34603 files changed, 44 insertions(+), 2 deletions(-)
src/analyze.cpp+11| ... | ... | @@ -8602,6 +8602,9 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) { |
| 8602 | 8602 | fn_type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, fn_type->data.fn.raw_di_type, |
| 8603 | 8603 | LLVMStoreSizeOfType(g->target_data_ref, fn_type->llvm_type), |
| 8604 | 8604 | LLVMABIAlignmentOfType(g->target_data_ref, fn_type->llvm_type), ""); |
| 8605 | ||
| 8606 | gen_param_types.deinit(); | |
| 8607 | param_di_types.deinit(); | |
| 8605 | 8608 | } |
| 8606 | 8609 | |
| 8607 | 8610 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) { |
| ... | ... | @@ -8636,6 +8639,9 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) { |
| 8636 | 8639 | fn->raw_type_ref = LLVMFunctionType(get_llvm_type(g, gen_return_type), |
| 8637 | 8640 | gen_param_types.items, gen_param_types.length, false); |
| 8638 | 8641 | fn->raw_di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0); |
| 8642 | ||
| 8643 | param_di_types.deinit(); | |
| 8644 | gen_param_types.deinit(); | |
| 8639 | 8645 | } |
| 8640 | 8646 | |
| 8641 | 8647 | static void resolve_llvm_types_anyerror(CodeGen *g) { |
| ... | ... | @@ -8660,6 +8666,8 @@ static void resolve_llvm_types_anyerror(CodeGen *g) { |
| 8660 | 8666 | tag_debug_align_in_bits, |
| 8661 | 8667 | err_enumerators.items, err_enumerators.length, |
| 8662 | 8668 | get_llvm_di_type(g, g->err_tag_type), ""); |
| 8669 | ||
| 8670 | err_enumerators.deinit(); | |
| 8663 | 8671 | } |
| 8664 | 8672 | |
| 8665 | 8673 | static void resolve_llvm_types_async_frame(CodeGen *g, ZigType *frame_type, ResolveStatus wanted_resolve_status) { |
| ... | ... | @@ -8805,6 +8813,9 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re |
| 8805 | 8813 | nullptr, di_element_types.items, di_element_types.length, 0, nullptr, ""); |
| 8806 | 8814 | |
| 8807 | 8815 | ZigLLVMReplaceTemporary(g->dbuilder, frame_header_di_type, replacement_di_type); |
| 8816 | ||
| 8817 | field_types.deinit(); | |
| 8818 | di_element_types.deinit(); | |
| 8808 | 8819 | } |
| 8809 | 8820 | |
| 8810 | 8821 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
src/codegen.cpp+13-2| ... | ... | @@ -4245,8 +4245,19 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa |
| 4245 | 4245 | if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull))) |
| 4246 | 4246 | codegen_report_errors_and_exit(g); |
| 4247 | 4247 | |
| 4248 | assert(field->gen_index != SIZE_MAX); | |
| 4249 | return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, ""); | |
| 4248 | src_assert(field->gen_index != SIZE_MAX, instruction->base.source_node); | |
| 4249 | LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, ""); | |
| 4250 | ZigType *res_type = instruction->base.value.type; | |
| 4251 | src_assert(res_type->id == ZigTypeIdPointer, instruction->base.source_node); | |
| 4252 | if (res_type->data.pointer.host_int_bytes != 0) { | |
| 4253 | // We generate packed structs with get_llvm_type_of_n_bytes, which is | |
| 4254 | // u8 for 1 byte or [n]u8 for multiple bytes. But the pointer to the type | |
| 4255 | // is supposed to be a pointer to the integer. So we bitcast it here. | |
| 4256 | LLVMTypeRef int_elem_type = LLVMIntType(8*res_type->data.pointer.host_int_bytes); | |
| 4257 | LLVMTypeRef integer_ptr_type = LLVMPointerType(int_elem_type, 0); | |
| 4258 | return LLVMBuildBitCast(g->builder, field_ptr_val, integer_ptr_type, ""); | |
| 4259 | } | |
| 4260 | return field_ptr_val; | |
| 4250 | 4261 | } |
| 4251 | 4262 | |
| 4252 | 4263 | static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable, |
test/stage1/behavior/struct.zig+20| ... | ... | @@ -689,3 +689,23 @@ test "non-packed struct with u128 entry in union" { |
| 689 | 689 | s.f2 = v2; |
| 690 | 690 | std.testing.expect(s.f2.Num == 123); |
| 691 | 691 | } |
| 692 | ||
| 693 | test "packed struct field passed to generic function" { | |
| 694 | const S = struct { | |
| 695 | const P = packed struct { | |
| 696 | b: u5, | |
| 697 | g: u5, | |
| 698 | r: u5, | |
| 699 | a: u1, | |
| 700 | }; | |
| 701 | ||
| 702 | fn genericReadPackedField(ptr: var) u5 { | |
| 703 | return ptr.*; | |
| 704 | } | |
| 705 | }; | |
| 706 | ||
| 707 | var p: S.P = undefined; | |
| 708 | p.b = 29; | |
| 709 | var loaded = S.genericReadPackedField(&p.b); | |
| 710 | expect(loaded == 29); | |
| 711 | } |