aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-06-25 23:06:53 -0700
committerGitHub <noreply@github.com>2023-06-25 23:06:53 -0700
commit40cf3f7ae5fbfb84b7af6b27e6296ee858b209ef (patch)
treee0c720d3fb38e61049a7411d7d176033e1616f69 /test
parentd98147414d084bc41b00ba9c0be8c7b82ad4e76c (diff)
parentb66865d0597124af02fed027a2d72c00b976a17f (diff)
downloadzig-40cf3f7ae5fbfb84b7af6b27e6296ee858b209ef.tar.gz
zig-40cf3f7ae5fbfb84b7af6b27e6296ee858b209ef.zip
Merge pull request #15995 from mlugg/fix/union-field-ptr-align
Sema: copy pointer alignment to union field pointers
Diffstat (limited to 'test')
-rw-r--r--test/behavior/struct.zig77
-rw-r--r--test/behavior/union.zig109
2 files changed, 186 insertions, 0 deletions
diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig
index 95b2718efd..08c4c37eee 100644
--- a/test/behavior/struct.zig
+++ b/test/behavior/struct.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const native_endian = builtin.target.cpu.arch.endian();
+const assert = std.debug.assert;
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const expectEqualSlices = std.testing.expectEqualSlices;
@@ -1637,3 +1638,79 @@ test "instantiate struct with comptime field" {
comptime std.debug.assert(things.foo == 1);
}
}
+
+test "struct field pointer has correct alignment" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var a: struct { x: u32 } = .{ .x = 123 };
+ var b: struct { x: u32 } align(1) = .{ .x = 456 };
+ var c: struct { x: u32 } align(64) = .{ .x = 789 };
+
+ const ap = &a.x;
+ const bp = &b.x;
+ const cp = &c.x;
+
+ comptime assert(@TypeOf(ap) == *u32);
+ comptime assert(@TypeOf(bp) == *align(1) u32);
+ comptime assert(@TypeOf(cp) == *u32); // undefined layout, cannot inherit larger alignment
+
+ try expectEqual(@as(u32, 123), ap.*);
+ try expectEqual(@as(u32, 456), bp.*);
+ try expectEqual(@as(u32, 789), cp.*);
+ }
+ };
+
+ try S.doTheTest();
+ try comptime S.doTheTest();
+}
+
+test "extern struct field pointer has correct alignment" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var a: extern struct { x: u32, y: u32 } = .{ .x = 1, .y = 2 };
+ var b: extern struct { x: u32, y: u32 } align(1) = .{ .x = 3, .y = 4 };
+ var c: extern struct { x: u32, y: u32 } align(64) = .{ .x = 5, .y = 6 };
+
+ const axp = &a.x;
+ const bxp = &b.x;
+ const cxp = &c.x;
+ const ayp = &a.y;
+ const byp = &b.y;
+ const cyp = &c.y;
+
+ comptime assert(@TypeOf(axp) == *u32);
+ comptime assert(@TypeOf(bxp) == *align(1) u32);
+ comptime assert(@TypeOf(cxp) == *align(64) u32); // first field, inherits larger alignment
+ comptime assert(@TypeOf(ayp) == *u32);
+ comptime assert(@TypeOf(byp) == *align(1) u32);
+ comptime assert(@TypeOf(cyp) == *u32);
+
+ try expectEqual(@as(u32, 1), axp.*);
+ try expectEqual(@as(u32, 3), bxp.*);
+ try expectEqual(@as(u32, 5), cxp.*);
+
+ try expectEqual(@as(u32, 2), ayp.*);
+ try expectEqual(@as(u32, 4), byp.*);
+ try expectEqual(@as(u32, 6), cyp.*);
+ }
+ };
+
+ try S.doTheTest();
+ try comptime S.doTheTest();
+}
diff --git a/test/behavior/union.zig b/test/behavior/union.zig
index 33cf1198ad..f7a481e311 100644
--- a/test/behavior/union.zig
+++ b/test/behavior/union.zig
@@ -1583,3 +1583,112 @@ test "coerce enum literal to union in result loc" {
try U.doTest(true);
try comptime U.doTest(true);
}
+
+test "defined-layout union field pointer has correct alignment" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest(comptime U: type) !void {
+ var a: U = .{ .x = 123 };
+ var b: U align(1) = .{ .x = 456 };
+ var c: U align(64) = .{ .x = 789 };
+
+ const ap = &a.x;
+ const bp = &b.x;
+ const cp = &c.x;
+
+ comptime assert(@TypeOf(ap) == *u32);
+ comptime assert(@TypeOf(bp) == *align(1) u32);
+ comptime assert(@TypeOf(cp) == *align(64) u32);
+
+ try expectEqual(@as(u32, 123), ap.*);
+ try expectEqual(@as(u32, 456), bp.*);
+ try expectEqual(@as(u32, 789), cp.*);
+ }
+ };
+
+ const U1 = extern union { x: u32 };
+ const U2 = packed union { x: u32 };
+
+ try S.doTheTest(U1);
+ try S.doTheTest(U2);
+ try comptime S.doTheTest(U1);
+ try comptime S.doTheTest(U2);
+}
+
+test "undefined-layout union field pointer has correct alignment" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest(comptime U: type) !void {
+ var a: U = .{ .x = 123 };
+ var b: U align(1) = .{ .x = 456 };
+ var c: U align(64) = .{ .x = 789 };
+
+ const ap = &a.x;
+ const bp = &b.x;
+ const cp = &c.x;
+
+ comptime assert(@TypeOf(ap) == *u32);
+ comptime assert(@TypeOf(bp) == *align(1) u32);
+ comptime assert(@TypeOf(cp) == *u32); // undefined layout so does not inherit larger aligns
+
+ try expectEqual(@as(u32, 123), ap.*);
+ try expectEqual(@as(u32, 456), bp.*);
+ try expectEqual(@as(u32, 789), cp.*);
+ }
+ };
+
+ const U1 = union { x: u32 };
+ const U2 = union(enum) { x: u32 };
+
+ try S.doTheTest(U1);
+ try S.doTheTest(U2);
+ try comptime S.doTheTest(U1);
+ try comptime S.doTheTest(U2);
+}
+
+test "packed union field pointer has correct alignment" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const U = packed union { x: u20 };
+ const S = packed struct(u24) { a: u2, u: U, b: u2 };
+
+ var a: S = undefined;
+ var b: S align(1) = undefined;
+ var c: S align(64) = undefined;
+
+ const ap = &a.u.x;
+ const bp = &b.u.x;
+ const cp = &c.u.x;
+
+ comptime assert(@TypeOf(ap) == *align(4:2:3) u20);
+ comptime assert(@TypeOf(bp) == *align(1:2:3) u20);
+ comptime assert(@TypeOf(cp) == *align(64:2:3) u20);
+
+ a.u = .{ .x = 123 };
+ b.u = .{ .x = 456 };
+ c.u = .{ .x = 789 };
+
+ try expectEqual(@as(u20, 123), ap.*);
+ try expectEqual(@as(u20, 456), bp.*);
+ try expectEqual(@as(u20, 789), cp.*);
+}