stage2: better codegen for byte-aligned packed struct fields

* Sema: handle overaligned packed struct field pointers
 * LLVM: handle byte-aligned packed struct field pointers
This commit is contained in:
Andrew Kelley
2022-06-07 20:51:14 -07:00
parent 70dc910086
commit 3e30ba3f20
4 changed files with 136 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
const assert = std.debug.assert;
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const native_endian = builtin.cpu.arch.endian();
@@ -305,3 +306,67 @@ test "regular in irregular packed struct" {
try expectEqual(@as(u16, 235), foo.bar.a);
try expectEqual(@as(u8, 42), foo.bar.b);
}
test "byte-aligned field pointer offsets" {
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
const S = struct {
const A = packed struct {
a: u8,
b: u8,
c: u8,
d: u8,
};
const B = packed struct {
a: u16,
b: u16,
};
fn doTheTest() !void {
var a: A = .{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
};
comptime assert(@TypeOf(&a.a) == *align(4) u8);
comptime assert(@TypeOf(&a.b) == *u8);
comptime assert(@TypeOf(&a.c) == *align(2) u8);
comptime assert(@TypeOf(&a.d) == *u8);
try expect(a.a == 1);
try expect(a.b == 2);
try expect(a.c == 3);
try expect(a.d == 4);
a.a += 1;
a.b += 1;
a.c += 1;
a.d += 1;
try expect(a.a == 2);
try expect(a.b == 3);
try expect(a.c == 4);
try expect(a.d == 5);
var b: B = .{
.a = 1,
.b = 2,
};
comptime assert(@TypeOf(&b.a) == *align(4) u16);
comptime assert(@TypeOf(&b.b) == *u16);
try expect(b.a == 1);
try expect(b.b == 2);
b.a += 1;
b.b += 1;
try expect(b.a == 2);
try expect(b.b == 3);
}
};
try S.doTheTest();
comptime try S.doTheTest();
}