| author | |
| committer | |
| log | 43c98dc11567eeb38be041c7dad179c53156f3df |
| tree | c512dfb131f73104cc6d1f3ef8db048e6105af1b |
| parent | 1a2468abfcd8b539193d943c1eefb71319cc7b88 |
This reverts commit 40cf3f7ae5fbfb84b7af6b27e6296ee858b209ef, reversing
changes made to d98147414d084bc41b00ba9c0be8c7b82ad4e76c.5 files changed, 9 insertions(+), 231 deletions(-)
lib/std/pdb.zig+2-2| ... | @@ -776,8 +776,8 @@ pub const Pdb = struct { | ... | @@ -776,8 +776,8 @@ pub const Pdb = struct { |
| 776 | } else 0; | 776 | } else 0; |
| 777 | 777 | ||
| 778 | const found_line_index = start_line_index + line_entry_idx * @sizeOf(LineNumberEntry); | 778 | const found_line_index = start_line_index + line_entry_idx * @sizeOf(LineNumberEntry); |
| 779 | const line_num_entry: *align(1) LineNumberEntry = @ptrCast(&subsect_info[found_line_index]); | 779 | const line_num_entry = @as(*align(1) LineNumberEntry, @ptrCast(&subsect_info[found_line_index])); |
| 780 | const flags: *align(1) LineNumberEntry.Flags = @ptrCast(&line_num_entry.Flags); | 780 | const flags = @as(*LineNumberEntry.Flags, @ptrCast(&line_num_entry.Flags)); |
| 781 | 781 | ||
| 782 | return debug.LineInfo{ | 782 | return debug.LineInfo{ |
| 783 | .file_name = source_file_name, | 783 | .file_name = source_file_name, |
src/Module.zig-1| ... | @@ -992,7 +992,6 @@ pub const Struct = struct { | ... | @@ -992,7 +992,6 @@ pub const Struct = struct { |
| 992 | is_comptime: bool, | 992 | is_comptime: bool, |
| 993 | 993 | ||
| 994 | /// Returns the field alignment. If the struct is packed, returns 0. | 994 | /// Returns the field alignment. If the struct is packed, returns 0. |
| 995 | /// Keep implementation in sync with `Sema.structFieldAlignment`. | ||
| 996 | pub fn alignment( | 995 | pub fn alignment( |
| 997 | field: Field, | 996 | field: Field, |
| 998 | mod: *Module, | 997 | mod: *Module, |
src/Sema.zig+7-42| ... | @@ -25879,9 +25879,6 @@ fn structFieldPtrByIndex( | ... | @@ -25879,9 +25879,6 @@ fn structFieldPtrByIndex( |
| 25879 | 25879 | ||
| 25880 | const target = mod.getTarget(); | 25880 | const target = mod.getTarget(); |
| 25881 | 25881 | ||
| 25882 | const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse | ||
| 25883 | try sema.typeAbiAlignment(struct_ptr_ty_info.child.toType()); | ||
| 25884 | |||
| 25885 | if (struct_obj.layout == .Packed) { | 25882 | if (struct_obj.layout == .Packed) { |
| 25886 | comptime assert(Type.packed_struct_layout_version == 2); | 25883 | comptime assert(Type.packed_struct_layout_version == 2); |
| 25887 | 25884 | ||
| ... | @@ -25903,6 +25900,8 @@ fn structFieldPtrByIndex( | ... | @@ -25903,6 +25900,8 @@ fn structFieldPtrByIndex( |
| 25903 | ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset; | 25900 | ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset; |
| 25904 | } | 25901 | } |
| 25905 | 25902 | ||
| 25903 | const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse | ||
| 25904 | struct_ptr_ty_info.child.toType().abiAlignment(mod); | ||
| 25906 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); | 25905 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); |
| 25907 | 25906 | ||
| 25908 | // If the field happens to be byte-aligned, simplify the pointer type. | 25907 | // If the field happens to be byte-aligned, simplify the pointer type. |
| ... | @@ -25926,13 +25925,8 @@ fn structFieldPtrByIndex( | ... | @@ -25926,13 +25925,8 @@ fn structFieldPtrByIndex( |
| 25926 | ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 }; | 25925 | ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 }; |
| 25927 | } | 25926 | } |
| 25928 | } | 25927 | } |
| 25929 | } else if (struct_obj.layout == .Extern and field_index == 0) { | ||
| 25930 | // This is the first field in memory, so can inherit the struct alignment | ||
| 25931 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); | ||
| 25932 | } else { | 25928 | } else { |
| 25933 | // Our alignment is capped at the field alignment | 25929 | ptr_ty_data.flags.alignment = field.abi_align; |
| 25934 | const field_align = try sema.structFieldAlignment(field, struct_obj.layout); | ||
| 25935 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(@min(field_align, parent_align)); | ||
| 25936 | } | 25930 | } |
| 25937 | 25931 | ||
| 25938 | const ptr_field_ty = try mod.ptrType(ptr_ty_data); | 25932 | const ptr_field_ty = try mod.ptrType(ptr_ty_data); |
| ... | @@ -26103,7 +26097,6 @@ fn unionFieldPtr( | ... | @@ -26103,7 +26097,6 @@ fn unionFieldPtr( |
| 26103 | assert(unresolved_union_ty.zigTypeTag(mod) == .Union); | 26097 | assert(unresolved_union_ty.zigTypeTag(mod) == .Union); |
| 26104 | 26098 | ||
| 26105 | const union_ptr_ty = sema.typeOf(union_ptr); | 26099 | const union_ptr_ty = sema.typeOf(union_ptr); |
| 26106 | const union_ptr_info = union_ptr_ty.ptrInfo(mod); | ||
| 26107 | const union_ty = try sema.resolveTypeFields(unresolved_union_ty); | 26100 | const union_ty = try sema.resolveTypeFields(unresolved_union_ty); |
| 26108 | const union_obj = mod.typeToUnion(union_ty).?; | 26101 | const union_obj = mod.typeToUnion(union_ty).?; |
| 26109 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); | 26102 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| ... | @@ -26111,16 +26104,10 @@ fn unionFieldPtr( | ... | @@ -26111,16 +26104,10 @@ fn unionFieldPtr( |
| 26111 | const ptr_field_ty = try mod.ptrType(.{ | 26104 | const ptr_field_ty = try mod.ptrType(.{ |
| 26112 | .child = field.ty.toIntern(), | 26105 | .child = field.ty.toIntern(), |
| 26113 | .flags = .{ | 26106 | .flags = .{ |
| 26114 | .is_const = union_ptr_info.flags.is_const, | 26107 | .is_const = !union_ptr_ty.ptrIsMutable(mod), |
| 26115 | .is_volatile = union_ptr_info.flags.is_volatile, | 26108 | .is_volatile = union_ptr_ty.isVolatilePtr(mod), |
| 26116 | .address_space = union_ptr_info.flags.address_space, | 26109 | .address_space = union_ptr_ty.ptrAddressSpace(mod), |
| 26117 | .alignment = if (union_obj.layout == .Auto) blk: { | 26110 | }, |
| 26118 | const union_align = union_ptr_info.flags.alignment.toByteUnitsOptional() orelse try sema.typeAbiAlignment(union_ty); | ||
| 26119 | const field_align = try sema.unionFieldAlignment(field); | ||
| 26120 | break :blk InternPool.Alignment.fromByteUnits(@min(union_align, field_align)); | ||
| 26121 | } else union_ptr_info.flags.alignment, | ||
| 26122 | }, | ||
| 26123 | .packed_offset = union_ptr_info.packed_offset, | ||
| 26124 | }); | 26111 | }); |
| 26125 | const enum_field_index = @as(u32, @intCast(union_obj.tag_ty.enumFieldIndex(field_name, mod).?)); | 26112 | const enum_field_index = @as(u32, @intCast(union_obj.tag_ty.enumFieldIndex(field_name, mod).?)); |
| 26126 | 26113 | ||
| ... | @@ -35987,28 +35974,6 @@ fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 { | ... | @@ -35987,28 +35974,6 @@ fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 { |
| 35987 | field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty))); | 35974 | field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty))); |
| 35988 | } | 35975 | } |
| 35989 | 35976 | ||
| 35990 | /// Keep implementation in sync with `Module.Struct.Field.alignment`. | ||
| 35991 | fn structFieldAlignment(sema: *Sema, field: Module.Struct.Field, layout: std.builtin.Type.ContainerLayout) !u32 { | ||
| 35992 | const mod = sema.mod; | ||
| 35993 | if (field.abi_align.toByteUnitsOptional()) |a| { | ||
| 35994 | assert(layout != .Packed); | ||
| 35995 | return @as(u32, @intCast(a)); | ||
| 35996 | } | ||
| 35997 | switch (layout) { | ||
| 35998 | .Packed => return 0, | ||
| 35999 | .Auto => if (mod.getTarget().ofmt != .c) { | ||
| 36000 | return sema.typeAbiAlignment(field.ty); | ||
| 36001 | }, | ||
| 36002 | .Extern => {}, | ||
| 36003 | } | ||
| 36004 | // extern | ||
| 36005 | const ty_abi_align = try sema.typeAbiAlignment(field.ty); | ||
| 36006 | if (field.ty.isAbiInt(mod) and field.ty.intInfo(mod).bits >= 128) { | ||
| 36007 | return @max(ty_abi_align, 16); | ||
| 36008 | } | ||
| 36009 | return ty_abi_align; | ||
| 36010 | } | ||
| 36011 | |||
| 36012 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. | 35977 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. |
| 36013 | pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { | 35978 | pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { |
| 36014 | const mod = sema.mod; | 35979 | const mod = sema.mod; |
test/behavior/struct.zig-77| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const native_endian = builtin.target.cpu.arch.endian(); | 3 | const native_endian = builtin.target.cpu.arch.endian(); |
| 4 | const assert = std.debug.assert; | ||
| 5 | const expect = std.testing.expect; | 4 | const expect = std.testing.expect; |
| 6 | const expectEqual = std.testing.expectEqual; | 5 | const expectEqual = std.testing.expectEqual; |
| 7 | const expectEqualSlices = std.testing.expectEqualSlices; | 6 | const expectEqualSlices = std.testing.expectEqualSlices; |
| ... | @@ -1635,79 +1634,3 @@ test "instantiate struct with comptime field" { | ... | @@ -1635,79 +1634,3 @@ test "instantiate struct with comptime field" { |
| 1635 | comptime std.debug.assert(things.foo == 1); | 1634 | comptime std.debug.assert(things.foo == 1); |
| 1636 | } | 1635 | } |
| 1637 | } | 1636 | } |
| 1638 | |||
| 1639 | test "struct field pointer has correct alignment" { | ||
| 1640 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1641 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1642 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1643 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1644 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1645 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1646 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1647 | |||
| 1648 | const S = struct { | ||
| 1649 | fn doTheTest() !void { | ||
| 1650 | var a: struct { x: u32 } = .{ .x = 123 }; | ||
| 1651 | var b: struct { x: u32 } align(1) = .{ .x = 456 }; | ||
| 1652 | var c: struct { x: u32 } align(64) = .{ .x = 789 }; | ||
| 1653 | |||
| 1654 | const ap = &a.x; | ||
| 1655 | const bp = &b.x; | ||
| 1656 | const cp = &c.x; | ||
| 1657 | |||
| 1658 | comptime assert(@TypeOf(ap) == *u32); | ||
| 1659 | comptime assert(@TypeOf(bp) == *align(1) u32); | ||
| 1660 | comptime assert(@TypeOf(cp) == *u32); // undefined layout, cannot inherit larger alignment | ||
| 1661 | |||
| 1662 | try expectEqual(@as(u32, 123), ap.*); | ||
| 1663 | try expectEqual(@as(u32, 456), bp.*); | ||
| 1664 | try expectEqual(@as(u32, 789), cp.*); | ||
| 1665 | } | ||
| 1666 | }; | ||
| 1667 | |||
| 1668 | try S.doTheTest(); | ||
| 1669 | try comptime S.doTheTest(); | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | test "extern struct field pointer has correct alignment" { | ||
| 1673 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1674 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1675 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1676 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1677 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1678 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1679 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1680 | |||
| 1681 | const S = struct { | ||
| 1682 | fn doTheTest() !void { | ||
| 1683 | var a: extern struct { x: u32, y: u32 } = .{ .x = 1, .y = 2 }; | ||
| 1684 | var b: extern struct { x: u32, y: u32 } align(1) = .{ .x = 3, .y = 4 }; | ||
| 1685 | var c: extern struct { x: u32, y: u32 } align(64) = .{ .x = 5, .y = 6 }; | ||
| 1686 | |||
| 1687 | const axp = &a.x; | ||
| 1688 | const bxp = &b.x; | ||
| 1689 | const cxp = &c.x; | ||
| 1690 | const ayp = &a.y; | ||
| 1691 | const byp = &b.y; | ||
| 1692 | const cyp = &c.y; | ||
| 1693 | |||
| 1694 | comptime assert(@TypeOf(axp) == *u32); | ||
| 1695 | comptime assert(@TypeOf(bxp) == *align(1) u32); | ||
| 1696 | comptime assert(@TypeOf(cxp) == *align(64) u32); // first field, inherits larger alignment | ||
| 1697 | comptime assert(@TypeOf(ayp) == *u32); | ||
| 1698 | comptime assert(@TypeOf(byp) == *align(1) u32); | ||
| 1699 | comptime assert(@TypeOf(cyp) == *u32); | ||
| 1700 | |||
| 1701 | try expectEqual(@as(u32, 1), axp.*); | ||
| 1702 | try expectEqual(@as(u32, 3), bxp.*); | ||
| 1703 | try expectEqual(@as(u32, 5), cxp.*); | ||
| 1704 | |||
| 1705 | try expectEqual(@as(u32, 2), ayp.*); | ||
| 1706 | try expectEqual(@as(u32, 4), byp.*); | ||
| 1707 | try expectEqual(@as(u32, 6), cyp.*); | ||
| 1708 | } | ||
| 1709 | }; | ||
| 1710 | |||
| 1711 | try S.doTheTest(); | ||
| 1712 | try comptime S.doTheTest(); | ||
| 1713 | } |
test/behavior/union.zig-109| ... | @@ -1583,112 +1583,3 @@ test "coerce enum literal to union in result loc" { | ... | @@ -1583,112 +1583,3 @@ test "coerce enum literal to union in result loc" { |
| 1583 | try U.doTest(true); | 1583 | try U.doTest(true); |
| 1584 | try comptime U.doTest(true); | 1584 | try comptime U.doTest(true); |
| 1585 | } | 1585 | } |
| 1586 | |||
| 1587 | test "defined-layout union field pointer has correct alignment" { | ||
| 1588 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1589 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1590 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1591 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1592 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1593 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1594 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1595 | |||
| 1596 | const S = struct { | ||
| 1597 | fn doTheTest(comptime U: type) !void { | ||
| 1598 | var a: U = .{ .x = 123 }; | ||
| 1599 | var b: U align(1) = .{ .x = 456 }; | ||
| 1600 | var c: U align(64) = .{ .x = 789 }; | ||
| 1601 | |||
| 1602 | const ap = &a.x; | ||
| 1603 | const bp = &b.x; | ||
| 1604 | const cp = &c.x; | ||
| 1605 | |||
| 1606 | comptime assert(@TypeOf(ap) == *u32); | ||
| 1607 | comptime assert(@TypeOf(bp) == *align(1) u32); | ||
| 1608 | comptime assert(@TypeOf(cp) == *align(64) u32); | ||
| 1609 | |||
| 1610 | try expectEqual(@as(u32, 123), ap.*); | ||
| 1611 | try expectEqual(@as(u32, 456), bp.*); | ||
| 1612 | try expectEqual(@as(u32, 789), cp.*); | ||
| 1613 | } | ||
| 1614 | }; | ||
| 1615 | |||
| 1616 | const U1 = extern union { x: u32 }; | ||
| 1617 | const U2 = packed union { x: u32 }; | ||
| 1618 | |||
| 1619 | try S.doTheTest(U1); | ||
| 1620 | try S.doTheTest(U2); | ||
| 1621 | try comptime S.doTheTest(U1); | ||
| 1622 | try comptime S.doTheTest(U2); | ||
| 1623 | } | ||
| 1624 | |||
| 1625 | test "undefined-layout union field pointer has correct alignment" { | ||
| 1626 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1627 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1628 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1629 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1630 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1631 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1632 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1633 | |||
| 1634 | const S = struct { | ||
| 1635 | fn doTheTest(comptime U: type) !void { | ||
| 1636 | var a: U = .{ .x = 123 }; | ||
| 1637 | var b: U align(1) = .{ .x = 456 }; | ||
| 1638 | var c: U align(64) = .{ .x = 789 }; | ||
| 1639 | |||
| 1640 | const ap = &a.x; | ||
| 1641 | const bp = &b.x; | ||
| 1642 | const cp = &c.x; | ||
| 1643 | |||
| 1644 | comptime assert(@TypeOf(ap) == *u32); | ||
| 1645 | comptime assert(@TypeOf(bp) == *align(1) u32); | ||
| 1646 | comptime assert(@TypeOf(cp) == *u32); // undefined layout so does not inherit larger aligns | ||
| 1647 | |||
| 1648 | try expectEqual(@as(u32, 123), ap.*); | ||
| 1649 | try expectEqual(@as(u32, 456), bp.*); | ||
| 1650 | try expectEqual(@as(u32, 789), cp.*); | ||
| 1651 | } | ||
| 1652 | }; | ||
| 1653 | |||
| 1654 | const U1 = union { x: u32 }; | ||
| 1655 | const U2 = union(enum) { x: u32 }; | ||
| 1656 | |||
| 1657 | try S.doTheTest(U1); | ||
| 1658 | try S.doTheTest(U2); | ||
| 1659 | try comptime S.doTheTest(U1); | ||
| 1660 | try comptime S.doTheTest(U2); | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | test "packed union field pointer has correct alignment" { | ||
| 1664 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1665 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1666 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1667 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1668 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1669 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1670 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 1671 | |||
| 1672 | const U = packed union { x: u20 }; | ||
| 1673 | const S = packed struct(u24) { a: u2, u: U, b: u2 }; | ||
| 1674 | |||
| 1675 | var a: S = undefined; | ||
| 1676 | var b: S align(1) = undefined; | ||
| 1677 | var c: S align(64) = undefined; | ||
| 1678 | |||
| 1679 | const ap = &a.u.x; | ||
| 1680 | const bp = &b.u.x; | ||
| 1681 | const cp = &c.u.x; | ||
| 1682 | |||
| 1683 | comptime assert(@TypeOf(ap) == *align(4:2:3) u20); | ||
| 1684 | comptime assert(@TypeOf(bp) == *align(1:2:3) u20); | ||
| 1685 | comptime assert(@TypeOf(cp) == *align(64:2:3) u20); | ||
| 1686 | |||
| 1687 | a.u = .{ .x = 123 }; | ||
| 1688 | b.u = .{ .x = 456 }; | ||
| 1689 | c.u = .{ .x = 789 }; | ||
| 1690 | |||
| 1691 | try expectEqual(@as(u20, 123), ap.*); | ||
| 1692 | try expectEqual(@as(u20, 456), bp.*); | ||
| 1693 | try expectEqual(@as(u20, 789), cp.*); | ||
| 1694 | } |