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) {...@@ -1896,9 +1896,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
1896 break;1896 break;
1897 }1897 }
1898 }1898 }
1899 size_t next_abi_align = (next_src_field_index == field_count) ?1899 size_t next_align = (next_src_field_index == field_count) ?
1900 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;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_abi_align);1901 next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_align);
1902 size_in_bits = next_offset * 8;1902 size_in_bits = next_offset * 8;
1903 }1903 }
1904 }1904 }
src/ir.cpp+4-3
...@@ -17127,6 +17127,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -17127,6 +17127,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
17127static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,17127static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
17128 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)17128 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)
17129{17129{
17130 Error err;
17130 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {17131 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
17131 case OnePossibleValueInvalid:17132 case OnePossibleValueInvalid:
17132 return ira->codegen->invalid_instruction;17133 return ira->codegen->invalid_instruction;
...@@ -17137,9 +17138,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -17137,9 +17138,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
17137 case OnePossibleValueNo:17138 case OnePossibleValueNo:
17138 break;17139 break;
17139 }17140 }
17141 if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusAlignmentKnown)))
17142 return ira->codegen->invalid_instruction;
17140 assert(struct_ptr->value.type->id == ZigTypeIdPointer);17143 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);
17143 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;17144 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
17144 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;17145 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
17145 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?17146 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...@@ -17147,7 +17148,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
17147 bool is_const = struct_ptr->value.type->data.pointer.is_const;17148 bool is_const = struct_ptr->value.type->data.pointer.is_const;
17148 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;17149 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
17149 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,17150 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,
17151 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),17152 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
17152 (uint32_t)host_int_bytes_for_result_type, false);17153 (uint32_t)host_int_bytes_for_result_type, false);
17153 if (instr_is_comptime(struct_ptr)) {17154 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" {...@@ -290,3 +290,18 @@ test "read 128-bit field from default aligned struct in global memory" {
290 expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);290 expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
291 expect(12 == default_aligned_global.badguy);291 expect(12 == default_aligned_global.badguy);
292}292}
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}