| author | |
| committer | |
| log | c248af3bdcd17c334e742d53a7ac7bda2422a688 |
| tree | 8d47cfaa0f653ef1b835c6e250178c763270000a |
| parent | 54454fd0102af8b25dbc85751d37fd265380d920 |
The LLVM backend was calculating the amount of padding solely based
on the payload size. However, in the case where there is no union
tag, this fails to take into account alignment.
Closes #118573 files changed, 24 insertions(+), 5 deletions(-)
lib/std/net/test.zig-3| ... | @@ -5,7 +5,6 @@ const mem = std.mem; | ... | @@ -5,7 +5,6 @@ const mem = std.mem; |
| 5 | const testing = std.testing; | 5 | const testing = std.testing; |
| 6 | 6 | ||
| 7 | test "parse and render IPv6 addresses" { | 7 | test "parse and render IPv6 addresses" { |
| 8 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | ||
| 9 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 8 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 10 | 9 | ||
| 11 | var buffer: [100]u8 = undefined; | 10 | var buffer: [100]u8 = undefined; |
| ... | @@ -68,7 +67,6 @@ test "invalid but parseable IPv6 scope ids" { | ... | @@ -68,7 +67,6 @@ test "invalid but parseable IPv6 scope ids" { |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | test "parse and render IPv4 addresses" { | 69 | test "parse and render IPv4 addresses" { |
| 71 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | ||
| 72 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 70 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 73 | 71 | ||
| 74 | var buffer: [18]u8 = undefined; | 72 | var buffer: [18]u8 = undefined; |
| ... | @@ -93,7 +91,6 @@ test "parse and render IPv4 addresses" { | ... | @@ -93,7 +91,6 @@ test "parse and render IPv4 addresses" { |
| 93 | } | 91 | } |
| 94 | 92 | ||
| 95 | test "parse and render UNIX addresses" { | 93 | test "parse and render UNIX addresses" { |
| 96 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | ||
| 97 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 94 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 98 | if (!net.has_unix_sockets) return error.SkipZigTest; | 95 | if (!net.has_unix_sockets) return error.SkipZigTest; |
| 99 | 96 |
src/codegen/llvm.zig+5-2| ... | @@ -2708,7 +2708,10 @@ pub const DeclGen = struct { | ... | @@ -2708,7 +2708,10 @@ pub const DeclGen = struct { |
| 2708 | if (layout.most_aligned_field_size == layout.payload_size) { | 2708 | if (layout.most_aligned_field_size == layout.payload_size) { |
| 2709 | break :t llvm_aligned_field_ty; | 2709 | break :t llvm_aligned_field_ty; |
| 2710 | } | 2710 | } |
| 2711 | const padding_len = @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size); | 2711 | const padding_len = if (layout.tag_size == 0) |
| 2712 | @intCast(c_uint, layout.abi_size - layout.most_aligned_field_size) | ||
| 2713 | else | ||
| 2714 | @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size); | ||
| 2712 | const fields: [2]*const llvm.Type = .{ | 2715 | const fields: [2]*const llvm.Type = .{ |
| 2713 | llvm_aligned_field_ty, | 2716 | llvm_aligned_field_ty, |
| 2714 | dg.context.intType(8).arrayType(padding_len), | 2717 | dg.context.intType(8).arrayType(padding_len), |
| ... | @@ -5756,7 +5759,7 @@ pub const FuncGen = struct { | ... | @@ -5756,7 +5759,7 @@ pub const FuncGen = struct { |
| 5756 | // First set the non-null bit. | 5759 | // First set the non-null bit. |
| 5757 | const indices: [2]*const llvm.Value = .{ | 5760 | const indices: [2]*const llvm.Value = .{ |
| 5758 | index_type.constNull(), // dereference the pointer | 5761 | index_type.constNull(), // dereference the pointer |
| 5759 | index_type.constInt(1, .False), // second field is the payload | 5762 | index_type.constInt(1, .False), // second field is the non-null bit |
| 5760 | }; | 5763 | }; |
| 5761 | const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); | 5764 | const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5762 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); | 5765 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
test/behavior/union.zig+19| ... | @@ -1194,3 +1194,22 @@ test "union tag is set when initiated as a temporary value at runtime" { | ... | @@ -1194,3 +1194,22 @@ test "union tag is set when initiated as a temporary value at runtime" { |
| 1194 | var b: u32 = 1; | 1194 | var b: u32 = 1; |
| 1195 | try (U{ .b = b }).doTheTest(); | 1195 | try (U{ .b = b }).doTheTest(); |
| 1196 | } | 1196 | } |
| 1197 | |||
| 1198 | test "extern union most-aligned field is smaller" { | ||
| 1199 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | ||
| 1200 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1202 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1203 | |||
| 1204 | const U = extern union { | ||
| 1205 | in6: extern struct { | ||
| 1206 | family: u16, | ||
| 1207 | port: u16, | ||
| 1208 | flowinfo: u32, | ||
| 1209 | addr: [20]u8, | ||
| 1210 | }, | ||
| 1211 | un: [110]u8, | ||
| 1212 | }; | ||
| 1213 | var a: ?U = .{ .un = [_]u8{0} ** 110 }; | ||
| 1214 | try expect(a != null); | ||
| 1215 | } |