diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-02 00:20:41 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-02 13:43:41 +0100 |
| commit | 15ff891f044102ba6515cb07f40805452420ea24 (patch) | |
| tree | 05e00c580057290dfcfccda0a8483668322aa11f /src/codegen.zig | |
| parent | 521bd2e94a3b32382b2d1de1e6185149032b49db (diff) | |
| download | zig-15ff891f044102ba6515cb07f40805452420ea24.tar.gz zig-15ff891f044102ba6515cb07f40805452420ea24.zip | |
stage2: pad out (non-packed) struct fields when lowering to bytes
* pad out (non-packed) struct fields when lowering to bytes to be
saved in the binary - prior to this change, fields would be
saved at non-aligned addresses leading to wrong accesses
* add a matching test case to `behavior/struct.zig` tests
* fix offset to field calculation in `struct_field_ptr` on `x86_64`
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index faafe79c13..bcd36358b1 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -373,11 +373,24 @@ pub fn generateSymbol( }, .Struct => { // TODO debug info - // TODO padding of struct members + const struct_obj = typed_value.ty.castTag(.@"struct").?.data; + if (struct_obj.layout == .Packed) { + return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for packed struct", + .{}, + ), + }; + } + + const struct_begin = code.items.len; const field_vals = typed_value.val.castTag(.@"struct").?.data; for (field_vals) |field_val, index| { const field_ty = typed_value.ty.structFieldType(index); if (!field_ty.hasRuntimeBits()) continue; + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = field_val, @@ -388,6 +401,16 @@ pub fn generateSymbol( }, .fail => |em| return Result{ .fail = em }, } + const unpadded_field_end = code.items.len - struct_begin; + + // Pad struct members if required + const target = bin_file.options.target; + const padded_field_end = typed_value.ty.structFieldOffset(index + 1, target); + const padding = try math.cast(usize, padded_field_end - unpadded_field_end); + + if (padding > 0) { + try code.writer().writeByteNTimes(0, padding); + } } return Result{ .appended = {} }; |
