authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-27 10:14:11-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-27 10:14:11-04:00
logffac0b02e75c9c620df11201ee70965856ba9ebf
tree3f8ccf411b164f6a371bff14d2b12130a7b5069a
parenta2e8ef77e2087e26c1449c56ad16efcea71679db
signaturelock-open Commit is signed but in an unrecognized format.

implement and test struct field explicit alignment


3 files changed, 22 insertions(+), 6 deletions(-)

src/analyze.cpp+3-3
......@@ -1896,9 +1896,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
18961896 break;
18971897 }
18981898 }
1899 size_t next_abi_align = (next_src_field_index == field_count) ?
1900 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
1901 next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_abi_align);
1899 size_t next_align = (next_src_field_index == field_count) ?
1900 abi_align : struct_type->data.structure.fields[next_src_field_index].align;
1901 next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_align);
19021902 size_in_bits = next_offset * 8;
19031903 }
19041904 }
src/ir.cpp+4-3
......@@ -17127,6 +17127,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
1712717127static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
1712817128 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)
1712917129{
17130 Error err;
1713017131 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
1713117132 case OnePossibleValueInvalid:
1713217133 return ira->codegen->invalid_instruction;
......@@ -17137,9 +17138,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
1713717138 case OnePossibleValueNo:
1713817139 break;
1713917140 }
17141 if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusAlignmentKnown)))
17142 return ira->codegen->invalid_instruction;
1714017143 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
17141 bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
17142 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
1714317144 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
1714417145 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
1714517146 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
......@@ -17147,7 +17148,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
1714717148 bool is_const = struct_ptr->value.type->data.pointer.is_const;
1714817149 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
1714917150 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17150 is_const, is_volatile, PtrLenSingle, align_bytes,
17151 is_const, is_volatile, PtrLenSingle, field->align,
1715117152 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
1715217153 (uint32_t)host_int_bytes_for_result_type, false);
1715317154 if (instr_is_comptime(struct_ptr)) {
test/stage1/behavior/align.zig+15
......@@ -290,3 +290,18 @@ test "read 128-bit field from default aligned struct in global memory" {
290290 expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
291291 expect(12 == default_aligned_global.badguy);
292292}
293
294test "struct field explicit alignment" {
295 const S = struct {
296 const Node = struct {
297 next: *Node,
298 massive_byte: u8 align(64),
299 };
300 };
301
302 var node: S.Node = undefined;
303 node.massive_byte = 100;
304 expect(node.massive_byte == 100);
305 comptime expect(@typeOf(&node.massive_byte) == *align(64) u8);
306 expect(@ptrToInt(&node.massive_byte) % 64 == 0);
307}