| ... | @@ -3,7 +3,6 @@ const builtin = @import("builtin"); | ... | @@ -3,7 +3,6 @@ const builtin = @import("builtin"); |
| 3 | const assert = std.debug.assert; | 3 | const assert = std.debug.assert; |
| 4 | const expect = std.testing.expect; | 4 | const expect = std.testing.expect; |
| 5 | const expectEqual = std.testing.expectEqual; | 5 | const expectEqual = std.testing.expectEqual; |
| 6 | const native_endian = builtin.cpu.arch.endian(); | | |
| 7 | | 6 | |
| 8 | test "flags in packed structs" { | 7 | test "flags in packed structs" { |
| 9 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -163,26 +162,24 @@ test "correct sizeOf and offsets in packed structs" { | ... | @@ -163,26 +162,24 @@ test "correct sizeOf and offsets in packed structs" { |
| 163 | try expectEqual(22, @bitOffsetOf(PStruct, "u10_b")); | 162 | try expectEqual(22, @bitOffsetOf(PStruct, "u10_b")); |
| 164 | try expectEqual(4, @sizeOf(PStruct)); | 163 | try expectEqual(4, @sizeOf(PStruct)); |
| 165 | | 164 | |
| 166 | if (native_endian == .little) { | 165 | const s1 = @as(PStruct, @bitCast(@as(u32, 0x12345678))); |
| 167 | const s1 = @as(PStruct, @bitCast(@as(u32, 0x12345678))); | 166 | try expectEqual(false, s1.bool_a); |
| 168 | try expectEqual(false, s1.bool_a); | 167 | try expectEqual(false, s1.bool_b); |
| 169 | try expectEqual(false, s1.bool_b); | 168 | try expectEqual(false, s1.bool_c); |
| 170 | try expectEqual(false, s1.bool_c); | 169 | try expectEqual(true, s1.bool_d); |
| 171 | try expectEqual(true, s1.bool_d); | 170 | try expectEqual(true, s1.bool_e); |
| 172 | try expectEqual(true, s1.bool_e); | 171 | try expectEqual(true, s1.bool_f); |
| 173 | try expectEqual(true, s1.bool_f); | 172 | try expectEqual(1, s1.u1_a); |
| 174 | try expectEqual(1, s1.u1_a); | 173 | try expectEqual(false, s1.bool_g); |
| 175 | try expectEqual(false, s1.bool_g); | 174 | try expectEqual(0, s1.u1_b); |
| 176 | try expectEqual(0, s1.u1_b); | 175 | try expectEqual(3, s1.u3_a); |
| 177 | try expectEqual(3, s1.u3_a); | 176 | try expectEqual(0b1101000101, s1.u10_a); |
| 178 | try expectEqual(0b1101000101, s1.u10_a); | 177 | try expectEqual(0b0001001000, s1.u10_b); |
| 179 | try expectEqual(0b0001001000, s1.u10_b); | 178 | |
| 180 | | 179 | const s2 = @as(packed struct { x: u1, y: u7, z: u24 }, @bitCast(@as(u32, 0xd5c71ff4))); |
| 181 | const s2 = @as(packed struct { x: u1, y: u7, z: u24 }, @bitCast(@as(u32, 0xd5c71ff4))); | 180 | try expectEqual(0, s2.x); |
| 182 | try expectEqual(0, s2.x); | 181 | try expectEqual(0b1111010, s2.y); |
| 183 | try expectEqual(0b1111010, s2.y); | 182 | try expectEqual(0xd5c71f, s2.z); |
| 184 | try expectEqual(0xd5c71f, s2.z); | | |
| 185 | } | | |
| 186 | } | 183 | } |
| 187 | | 184 | |
| 188 | test "nested packed structs" { | 185 | test "nested packed structs" { |
| ... | @@ -202,15 +199,13 @@ test "nested packed structs" { | ... | @@ -202,15 +199,13 @@ test "nested packed structs" { |
| 202 | try expectEqual(3, @offsetOf(S3, "y")); | 199 | try expectEqual(3, @offsetOf(S3, "y")); |
| 203 | try expectEqual(24, @bitOffsetOf(S3, "y")); | 200 | try expectEqual(24, @bitOffsetOf(S3, "y")); |
| 204 | | 201 | |
| 205 | if (native_endian == .little) { | 202 | const s3 = @as(S3Padded, @bitCast(@as(u64, 0xe952d5c71ff4))).s3; |
| 206 | const s3 = @as(S3Padded, @bitCast(@as(u64, 0xe952d5c71ff4))).s3; | 203 | try expectEqual(0xf4, s3.x.a); |
| 207 | try expectEqual(0xf4, s3.x.a); | 204 | try expectEqual(0x1f, s3.x.b); |
| 208 | try expectEqual(0x1f, s3.x.b); | 205 | try expectEqual(0xc7, s3.x.c); |
| 209 | try expectEqual(0xc7, s3.x.c); | 206 | try expectEqual(0xd5, s3.y.d); |
| 210 | try expectEqual(0xd5, s3.y.d); | 207 | try expectEqual(0x52, s3.y.e); |
| 211 | try expectEqual(0x52, s3.y.e); | 208 | try expectEqual(0xe9, s3.y.f); |
| 212 | try expectEqual(0xe9, s3.y.f); | | |
| 213 | } | | |
| 214 | | 209 | |
| 215 | const S4 = packed struct { a: i32, b: i8 }; | 210 | const S4 = packed struct { a: i32, b: i8 }; |
| 216 | const S5 = packed struct { a: i32, b: i8, c: S4 }; | 211 | const S5 = packed struct { a: i32, b: i8, c: S4 }; |
| ... | @@ -252,7 +247,6 @@ test "nested packed struct unaligned" { | ... | @@ -252,7 +247,6 @@ test "nested packed struct unaligned" { |
| 252 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 247 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 253 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 248 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 254 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 249 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 255 | if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet | | |
| 256 | | 250 | |
| 257 | const S1 = packed struct { | 251 | const S1 = packed struct { |
| 258 | a: u4, | 252 | a: u4, |
| ... | @@ -344,21 +338,12 @@ test "byte-aligned field pointer offsets" { | ... | @@ -344,21 +338,12 @@ test "byte-aligned field pointer offsets" { |
| 344 | .c = 3, | 338 | .c = 3, |
| 345 | .d = 4, | 339 | .d = 4, |
| 346 | }; | 340 | }; |
| 347 | switch (comptime builtin.cpu.arch.endian()) { | 341 | |
| 348 | .little => { | 342 | comptime assert(@TypeOf(&a.a) == *align(4:0:4) u8); |
| 349 | comptime assert(@TypeOf(&a.a) == *align(4) u8); | 343 | comptime assert(@TypeOf(&a.b) == *align(4:8:4) u8); |
| 350 | comptime assert(@TypeOf(&a.b) == *u8); | 344 | comptime assert(@TypeOf(&a.c) == *align(4:16:4) u8); |
| 351 | comptime assert(@TypeOf(&a.c) == *align(2) u8); | 345 | comptime assert(@TypeOf(&a.d) == *align(4:24:4) u8); |
| 352 | comptime assert(@TypeOf(&a.d) == *u8); | 346 | |
| 353 | }, | | |
| 354 | .big => { | | |
| 355 | // TODO re-evaluate packed struct endianness | | |
| 356 | comptime assert(@TypeOf(&a.a) == *align(4:0:4) u8); | | |
| 357 | comptime assert(@TypeOf(&a.b) == *align(4:8:4) u8); | | |
| 358 | comptime assert(@TypeOf(&a.c) == *align(4:16:4) u8); | | |
| 359 | comptime assert(@TypeOf(&a.d) == *align(4:24:4) u8); | | |
| 360 | }, | | |
| 361 | } | | |
| 362 | try expect(a.a == 1); | 347 | try expect(a.a == 1); |
| 363 | try expect(a.b == 2); | 348 | try expect(a.b == 2); |
| 364 | try expect(a.c == 3); | 349 | try expect(a.c == 3); |
| ... | @@ -392,16 +377,10 @@ test "byte-aligned field pointer offsets" { | ... | @@ -392,16 +377,10 @@ test "byte-aligned field pointer offsets" { |
| 392 | .a = 1, | 377 | .a = 1, |
| 393 | .b = 2, | 378 | .b = 2, |
| 394 | }; | 379 | }; |
| 395 | switch (comptime builtin.cpu.arch.endian()) { | 380 | |
| 396 | .little => { | 381 | comptime assert(@TypeOf(&b.a) == *align(4:0:4) u16); |
| 397 | comptime assert(@TypeOf(&b.a) == *align(4) u16); | 382 | comptime assert(@TypeOf(&b.b) == *align(4:16:4) u16); |
| 398 | comptime assert(@TypeOf(&b.b) == *u16); | 383 | |
| 399 | }, | | |
| 400 | .big => { | | |
| 401 | comptime assert(@TypeOf(&b.a) == *align(4:0:4) u16); | | |
| 402 | comptime assert(@TypeOf(&b.b) == *align(4:16:4) u16); | | |
| 403 | }, | | |
| 404 | } | | |
| 405 | try expect(b.a == 1); | 384 | try expect(b.a == 1); |
| 406 | try expect(b.b == 2); | 385 | try expect(b.b == 2); |
| 407 | | 386 | |
| ... | @@ -426,7 +405,6 @@ test "nested packed struct field pointers" { | ... | @@ -426,7 +405,6 @@ test "nested packed struct field pointers" { |
| 426 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 405 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 427 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access | 406 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access |
| 428 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 407 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 429 | if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet | | |
| 430 | | 408 | |
| 431 | const S2 = packed struct { | 409 | const S2 = packed struct { |
| 432 | base: u8, | 410 | base: u8, |
| ... | @@ -483,7 +461,6 @@ test "@intFromPtr on a packed struct field" { | ... | @@ -483,7 +461,6 @@ test "@intFromPtr on a packed struct field" { |
| 483 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 461 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 484 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 462 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 485 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 463 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 486 | if (native_endian != .little) return error.SkipZigTest; | | |
| 487 | | 464 | |
| 488 | const S = struct { | 465 | const S = struct { |
| 489 | const P = packed struct { | 466 | const P = packed struct { |
| ... | @@ -498,14 +475,13 @@ test "@intFromPtr on a packed struct field" { | ... | @@ -498,14 +475,13 @@ test "@intFromPtr on a packed struct field" { |
| 498 | .z = 0, | 475 | .z = 0, |
| 499 | }; | 476 | }; |
| 500 | }; | 477 | }; |
| 501 | try expect(@intFromPtr(&S.p0.z) - @intFromPtr(&S.p0.x) == 2); | 478 | try expect(@intFromPtr(&S.p0.z) - @intFromPtr(&S.p0.x) == 0); |
| 502 | } | 479 | } |
| 503 | | 480 | |
| 504 | test "@intFromPtr on a packed struct field unaligned and nested" { | 481 | test "@intFromPtr on a packed struct field unaligned and nested" { |
| 505 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 482 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 506 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 483 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 507 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 484 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 508 | if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet | | |
| 509 | | 485 | |
| 510 | const S1 = packed struct { | 486 | const S1 = packed struct { |
| 511 | a: u4, | 487 | a: u4, |
| ... | @@ -565,16 +541,16 @@ test "@intFromPtr on a packed struct field unaligned and nested" { | ... | @@ -565,16 +541,16 @@ test "@intFromPtr on a packed struct field unaligned and nested" { |
| 565 | else => {}, | 541 | else => {}, |
| 566 | } | 542 | } |
| 567 | try expect(@intFromPtr(&S2.s.base) - @intFromPtr(&S2.s) == 0); | 543 | try expect(@intFromPtr(&S2.s.base) - @intFromPtr(&S2.s) == 0); |
| 568 | try expect(@intFromPtr(&S2.s.p0.a) - @intFromPtr(&S2.s) == 1); | 544 | try expect(@intFromPtr(&S2.s.p0.a) - @intFromPtr(&S2.s) == 0); |
| 569 | try expect(@intFromPtr(&S2.s.p0.b) - @intFromPtr(&S2.s) == 1); | 545 | try expect(@intFromPtr(&S2.s.p0.b) - @intFromPtr(&S2.s) == 0); |
| 570 | try expect(@intFromPtr(&S2.s.p0.c) - @intFromPtr(&S2.s) == 2); | 546 | try expect(@intFromPtr(&S2.s.p0.c) - @intFromPtr(&S2.s) == 0); |
| 571 | try expect(@intFromPtr(&S2.s.bit0) - @intFromPtr(&S2.s) == 0); | 547 | try expect(@intFromPtr(&S2.s.bit0) - @intFromPtr(&S2.s) == 0); |
| 572 | try expect(@intFromPtr(&S2.s.p1.a) - @intFromPtr(&S2.s) == 0); | 548 | try expect(@intFromPtr(&S2.s.p1.a) - @intFromPtr(&S2.s) == 0); |
| 573 | try expect(@intFromPtr(&S2.s.p2.a) - @intFromPtr(&S2.s) == 0); | 549 | try expect(@intFromPtr(&S2.s.p2.a) - @intFromPtr(&S2.s) == 0); |
| 574 | try expect(@intFromPtr(&S2.s.p2.b) - @intFromPtr(&S2.s) == 5); | 550 | try expect(@intFromPtr(&S2.s.p2.b) - @intFromPtr(&S2.s) == 0); |
| 575 | try expect(@intFromPtr(&S2.s.p3.a) - @intFromPtr(&S2.s) == 6); | 551 | try expect(@intFromPtr(&S2.s.p3.a) - @intFromPtr(&S2.s) == 0); |
| 576 | try expect(@intFromPtr(&S2.s.p3.b) - @intFromPtr(&S2.s) == 6); | 552 | try expect(@intFromPtr(&S2.s.p3.b) - @intFromPtr(&S2.s) == 0); |
| 577 | try expect(@intFromPtr(&S2.s.p3.c) - @intFromPtr(&S2.s) == 7); | 553 | try expect(@intFromPtr(&S2.s.p3.c) - @intFromPtr(&S2.s) == 0); |
| 578 | | 554 | |
| 579 | const S3 = packed struct { | 555 | const S3 = packed struct { |
| 580 | pad: u8, | 556 | pad: u8, |
| ... | @@ -597,7 +573,7 @@ test "@intFromPtr on a packed struct field unaligned and nested" { | ... | @@ -597,7 +573,7 @@ test "@intFromPtr on a packed struct field unaligned and nested" { |
| 597 | comptime assert(@TypeOf(&S3.v0.s.v) == *align(4:10:4) u3); | 573 | comptime assert(@TypeOf(&S3.v0.s.v) == *align(4:10:4) u3); |
| 598 | comptime assert(@TypeOf(&S3.v0.s.s.v) == *align(4:13:4) u2); | 574 | comptime assert(@TypeOf(&S3.v0.s.s.v) == *align(4:13:4) u2); |
| 599 | comptime assert(@TypeOf(&S3.v0.s.s.s.bit0) == *align(4:15:4) u1); | 575 | comptime assert(@TypeOf(&S3.v0.s.s.s.bit0) == *align(4:15:4) u1); |
| 600 | comptime assert(@TypeOf(&S3.v0.s.s.s.byte) == *align(2) u8); | 576 | comptime assert(@TypeOf(&S3.v0.s.s.s.byte) == *align(4:16:4) u8); |
| 601 | comptime assert(@TypeOf(&S3.v0.s.s.s.bit1) == *align(4:24:4) u1); | 577 | comptime assert(@TypeOf(&S3.v0.s.s.s.bit1) == *align(4:24:4) u1); |
| 602 | try expect(@intFromPtr(&S3.v0.v) - @intFromPtr(&S3.v0) == 0); | 578 | try expect(@intFromPtr(&S3.v0.v) - @intFromPtr(&S3.v0) == 0); |
| 603 | try expect(@intFromPtr(&S3.v0.s) - @intFromPtr(&S3.v0) == 0); | 579 | try expect(@intFromPtr(&S3.v0.s) - @intFromPtr(&S3.v0) == 0); |
| ... | @@ -606,7 +582,7 @@ test "@intFromPtr on a packed struct field unaligned and nested" { | ... | @@ -606,7 +582,7 @@ test "@intFromPtr on a packed struct field unaligned and nested" { |
| 606 | try expect(@intFromPtr(&S3.v0.s.s.v) - @intFromPtr(&S3.v0) == 0); | 582 | try expect(@intFromPtr(&S3.v0.s.s.v) - @intFromPtr(&S3.v0) == 0); |
| 607 | try expect(@intFromPtr(&S3.v0.s.s.s) - @intFromPtr(&S3.v0) == 0); | 583 | try expect(@intFromPtr(&S3.v0.s.s.s) - @intFromPtr(&S3.v0) == 0); |
| 608 | try expect(@intFromPtr(&S3.v0.s.s.s.bit0) - @intFromPtr(&S3.v0) == 0); | 584 | try expect(@intFromPtr(&S3.v0.s.s.s.bit0) - @intFromPtr(&S3.v0) == 0); |
| 609 | try expect(@intFromPtr(&S3.v0.s.s.s.byte) - @intFromPtr(&S3.v0) == 2); | 585 | try expect(@intFromPtr(&S3.v0.s.s.s.byte) - @intFromPtr(&S3.v0) == 0); |
| 610 | try expect(@intFromPtr(&S3.v0.s.s.s.bit1) - @intFromPtr(&S3.v0) == 0); | 586 | try expect(@intFromPtr(&S3.v0.s.s.s.bit1) - @intFromPtr(&S3.v0) == 0); |
| 611 | } | 587 | } |
| 612 | | 588 | |
| ... | @@ -915,17 +891,8 @@ test "overaligned pointer to packed struct" { | ... | @@ -915,17 +891,8 @@ test "overaligned pointer to packed struct" { |
| 915 | const S = packed struct { a: u32, b: u32 }; | 891 | const S = packed struct { a: u32, b: u32 }; |
| 916 | var foo: S align(4) = .{ .a = 123, .b = 456 }; | 892 | var foo: S align(4) = .{ .a = 123, .b = 456 }; |
| 917 | const ptr: *align(4) S = &foo; | 893 | const ptr: *align(4) S = &foo; |
| 918 | switch (comptime builtin.cpu.arch.endian()) { | 894 | const ptr_to_a: *align(4:0:8) u32 = &ptr.a; |
| 919 | .little => { | 895 | try expect(ptr_to_a.* == 123); |
| 920 | const ptr_to_b: *u32 = &ptr.b; | | |
| 921 | try expect(ptr_to_b.* == 456); | | |
| 922 | }, | | |
| 923 | .big => { | | |
| 924 | // Byte aligned packed struct field pointers have not been implemented yet. | | |
| 925 | const ptr_to_a: *align(4:0:8) u32 = &ptr.a; | | |
| 926 | try expect(ptr_to_a.* == 123); | | |
| 927 | }, | | |
| 928 | } | | |
| 929 | } | 896 | } |
| 930 | | 897 | |
| 931 | test "packed struct initialized in bitcast" { | 898 | test "packed struct initialized in bitcast" { |