authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-26 14:54:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-26 14:54:53-04:00
log589201b10492e2aba06df7860666cef7c6916acc
tree1aeeeb504292b51febada0df744abc3ddc92e27c
parentdcfd15a7f0ed5159afad47915a11d1dd8315cbe8
signaturelock-open Commit is signed but in an unrecognized format.

fix variables which are pointers to packed struct fields

closes #1121

2 files changed, 31 insertions(+), 11 deletions(-)

src/analyze.cpp+18-11
...@@ -489,20 +489,27 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -489,20 +489,27 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
489 entry->zero_bits = !type_has_bits(child_type);489 entry->zero_bits = !type_has_bits(child_type);
490490
491 if (!entry->zero_bits) {491 if (!entry->zero_bits) {
492 if (is_const || is_volatile || host_int_bytes != 0 || byte_alignment != 0 ||492 if (is_const || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle || bit_offset_in_host != 0) {
493 ptr_len != PtrLenSingle)493 ZigType *peer_type = get_pointer_to_type_extra(g, child_type, false, false,
494 {494 PtrLenSingle, 0, 0, host_int_bytes);
495 ZigType *peer_type = get_pointer_to_type(g, child_type, false);
496 entry->type_ref = peer_type->type_ref;495 entry->type_ref = peer_type->type_ref;
497 entry->di_type = peer_type->di_type;496 entry->di_type = peer_type->di_type;
498 } else {497 } else {
499 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);498 if (host_int_bytes == 0) {
500499 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
501 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);500 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
502 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);501 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);
503 assert(child_type->di_type);502 assert(child_type->di_type);
504 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type,503 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type,
505 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));504 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));
505 } else {
506 ZigType *host_int_type = get_int_type(g, false, host_int_bytes * 8);
507 entry->type_ref = LLVMPointerType(host_int_type->type_ref, 0);
508 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, host_int_type->type_ref);
509 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, host_int_type->type_ref);
510 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, host_int_type->di_type,
511 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));
512 }
506 }513 }
507 } else {514 } else {
508 assert(byte_alignment == 0);515 assert(byte_alignment == 0);
test/cases/struct.zig+13
...@@ -453,3 +453,16 @@ test "implicit cast packed struct field to const ptr" {...@@ -453,3 +453,16 @@ test "implicit cast packed struct field to const ptr" {
453 const res = LevelUpMove.toInt(lup.level);453 const res = LevelUpMove.toInt(lup.level);
454 assert(res == 12);454 assert(res == 12);
455}455}
456
457test "pointer to packed struct member in a stack variable" {
458 const S = packed struct {
459 a: u2,
460 b: u2,
461 };
462
463 var s = S{ .a = 2, .b = 0 };
464 var b_ptr = &s.b;
465 assert(s.b == 0);
466 b_ptr.* = 2;
467 assert(s.b == 2);
468}