mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 00:57:04 +00:00
fix non-byte-aligned packed struct field...
...passed as generic fn parameter causing invalid LLVM IR. closes #3460
This commit is contained in:
parent
7495fd8cb9
commit
9050cd847a
@ -8602,6 +8602,9 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
|
||||
fn_type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, fn_type->data.fn.raw_di_type,
|
||||
LLVMStoreSizeOfType(g->target_data_ref, fn_type->llvm_type),
|
||||
LLVMABIAlignmentOfType(g->target_data_ref, fn_type->llvm_type), "");
|
||||
|
||||
gen_param_types.deinit();
|
||||
param_di_types.deinit();
|
||||
}
|
||||
|
||||
void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
|
||||
@ -8636,6 +8639,9 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
|
||||
fn->raw_type_ref = LLVMFunctionType(get_llvm_type(g, gen_return_type),
|
||||
gen_param_types.items, gen_param_types.length, false);
|
||||
fn->raw_di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0);
|
||||
|
||||
param_di_types.deinit();
|
||||
gen_param_types.deinit();
|
||||
}
|
||||
|
||||
static void resolve_llvm_types_anyerror(CodeGen *g) {
|
||||
@ -8660,6 +8666,8 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
|
||||
tag_debug_align_in_bits,
|
||||
err_enumerators.items, err_enumerators.length,
|
||||
get_llvm_di_type(g, g->err_tag_type), "");
|
||||
|
||||
err_enumerators.deinit();
|
||||
}
|
||||
|
||||
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
|
||||
nullptr, di_element_types.items, di_element_types.length, 0, nullptr, "");
|
||||
|
||||
ZigLLVMReplaceTemporary(g->dbuilder, frame_header_di_type, replacement_di_type);
|
||||
|
||||
field_types.deinit();
|
||||
di_element_types.deinit();
|
||||
}
|
||||
|
||||
static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
|
||||
|
@ -4245,8 +4245,19 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
|
||||
if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull)))
|
||||
codegen_report_errors_and_exit(g);
|
||||
|
||||
assert(field->gen_index != SIZE_MAX);
|
||||
return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
|
||||
src_assert(field->gen_index != SIZE_MAX, instruction->base.source_node);
|
||||
LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
|
||||
ZigType *res_type = instruction->base.value.type;
|
||||
src_assert(res_type->id == ZigTypeIdPointer, instruction->base.source_node);
|
||||
if (res_type->data.pointer.host_int_bytes != 0) {
|
||||
// We generate packed structs with get_llvm_type_of_n_bytes, which is
|
||||
// u8 for 1 byte or [n]u8 for multiple bytes. But the pointer to the type
|
||||
// is supposed to be a pointer to the integer. So we bitcast it here.
|
||||
LLVMTypeRef int_elem_type = LLVMIntType(8*res_type->data.pointer.host_int_bytes);
|
||||
LLVMTypeRef integer_ptr_type = LLVMPointerType(int_elem_type, 0);
|
||||
return LLVMBuildBitCast(g->builder, field_ptr_val, integer_ptr_type, "");
|
||||
}
|
||||
return field_ptr_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
|
||||
|
@ -689,3 +689,23 @@ test "non-packed struct with u128 entry in union" {
|
||||
s.f2 = v2;
|
||||
std.testing.expect(s.f2.Num == 123);
|
||||
}
|
||||
|
||||
test "packed struct field passed to generic function" {
|
||||
const S = struct {
|
||||
const P = packed struct {
|
||||
b: u5,
|
||||
g: u5,
|
||||
r: u5,
|
||||
a: u1,
|
||||
};
|
||||
|
||||
fn genericReadPackedField(ptr: var) u5 {
|
||||
return ptr.*;
|
||||
}
|
||||
};
|
||||
|
||||
var p: S.P = undefined;
|
||||
p.b = 29;
|
||||
var loaded = S.genericReadPackedField(&p.b);
|
||||
expect(loaded == 29);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user