| author | |
| committer | |
| log | 7dd3c3814de0caf808bc112aa07044cdd8bba135 |
| tree | 3ed6db0680f013c496535d447261462129454975 |
| parent | dd1338b0e6280b10b9b62ca73bf9ece34bd8524e |
| signature |
closes #1442
zig needed to insert explicit padding into this structure before
it got bitcasted.5 files changed, 73 insertions(+), 28 deletions(-)
src/analyze.cpp+13-2| ... | ... | @@ -5882,12 +5882,23 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5882 | 5882 | } |
| 5883 | 5883 | case ZigTypeIdErrorUnion: |
| 5884 | 5884 | { |
| 5885 | buf_appendf(buf, "(error union %s constant)", buf_ptr(&type_entry->name)); | |
| 5885 | buf_appendf(buf, "%s(", buf_ptr(&type_entry->name)); | |
| 5886 | if (const_val->data.x_err_union.err == nullptr) { | |
| 5887 | render_const_value(g, buf, const_val->data.x_err_union.payload); | |
| 5888 | } else { | |
| 5889 | buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->data.error_union.err_set_type->name), | |
| 5890 | buf_ptr(&const_val->data.x_err_union.err->name)); | |
| 5891 | } | |
| 5892 | buf_appendf(buf, ")"); | |
| 5886 | 5893 | return; |
| 5887 | 5894 | } |
| 5888 | 5895 | case ZigTypeIdUnion: |
| 5889 | 5896 | { |
| 5890 | buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name)); | |
| 5897 | uint64_t tag = bigint_as_unsigned(&const_val->data.x_union.tag); | |
| 5898 | TypeUnionField *field = &type_entry->data.unionation.fields[tag]; | |
| 5899 | buf_appendf(buf, "%s { .%s = ", buf_ptr(&type_entry->name), buf_ptr(field->name)); | |
| 5900 | render_const_value(g, buf, const_val->data.x_union.payload); | |
| 5901 | buf_append_str(buf, "}"); | |
| 5891 | 5902 | return; |
| 5892 | 5903 | } |
| 5893 | 5904 | case ZigTypeIdErrorSet: |
src/codegen.cpp+29-9| ... | ... | @@ -5870,13 +5870,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 5870 | 5870 | |
| 5871 | 5871 | if (make_unnamed_struct) { |
| 5872 | 5872 | LLVMValueRef result = LLVMConstStruct(fields, 2, false); |
| 5873 | size_t expected_sz = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); | |
| 5874 | size_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result)); | |
| 5875 | if (actual_sz < expected_sz) { | |
| 5876 | unsigned pad_sz = expected_sz - actual_sz; | |
| 5873 | uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1); | |
| 5874 | uint64_t end_offset = last_field_offset + | |
| 5875 | LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1])); | |
| 5876 | uint64_t expected_sz = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); | |
| 5877 | unsigned pad_sz = expected_sz - end_offset; | |
| 5878 | if (pad_sz != 0) { | |
| 5877 | 5879 | fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)); |
| 5878 | 5880 | result = LLVMConstStruct(fields, 3, false); |
| 5879 | 5881 | } |
| 5882 | uint64_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result)); | |
| 5883 | assert(actual_sz == expected_sz); | |
| 5880 | 5884 | return result; |
| 5881 | 5885 | } else { |
| 5882 | 5886 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); |
| ... | ... | @@ -5917,13 +5921,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 5917 | 5921 | err_payload_value = gen_const_val(g, payload_val, ""); |
| 5918 | 5922 | make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value); |
| 5919 | 5923 | } |
| 5920 | LLVMValueRef fields[] = { | |
| 5921 | err_tag_value, | |
| 5922 | err_payload_value, | |
| 5923 | }; | |
| 5924 | 5924 | if (make_unnamed_struct) { |
| 5925 | return LLVMConstStruct(fields, 2, false); | |
| 5925 | uint64_t payload_off = LLVMOffsetOfElement(g->target_data_ref, type_entry->type_ref, 1); | |
| 5926 | uint64_t err_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(err_tag_value)); | |
| 5927 | unsigned pad_sz = payload_off - err_sz; | |
| 5928 | if (pad_sz == 0) { | |
| 5929 | LLVMValueRef fields[] = { | |
| 5930 | err_tag_value, | |
| 5931 | err_payload_value, | |
| 5932 | }; | |
| 5933 | return LLVMConstStruct(fields, 2, false); | |
| 5934 | } else { | |
| 5935 | LLVMValueRef fields[] = { | |
| 5936 | err_tag_value, | |
| 5937 | LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)), | |
| 5938 | err_payload_value, | |
| 5939 | }; | |
| 5940 | return LLVMConstStruct(fields, 3, false); | |
| 5941 | } | |
| 5926 | 5942 | } else { |
| 5943 | LLVMValueRef fields[] = { | |
| 5944 | err_tag_value, | |
| 5945 | err_payload_value, | |
| 5946 | }; | |
| 5927 | 5947 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); |
| 5928 | 5948 | } |
| 5929 | 5949 | } |
std/os/index.zig+19-17| ... | ... | @@ -343,23 +343,25 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void { |
| 343 | 343 | const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len)); |
| 344 | 344 | const rc = posix.write(fd, bytes.ptr + index, amt_to_write); |
| 345 | 345 | const write_err = posix.getErrno(rc); |
| 346 | if (write_err > 0) { | |
| 347 | return switch (write_err) { | |
| 348 | posix.EINTR => continue, | |
| 349 | posix.EINVAL, posix.EFAULT => unreachable, | |
| 350 | posix.EAGAIN => PosixWriteError.WouldBlock, | |
| 351 | posix.EBADF => PosixWriteError.FileClosed, | |
| 352 | posix.EDESTADDRREQ => PosixWriteError.DestinationAddressRequired, | |
| 353 | posix.EDQUOT => PosixWriteError.DiskQuota, | |
| 354 | posix.EFBIG => PosixWriteError.FileTooBig, | |
| 355 | posix.EIO => PosixWriteError.InputOutput, | |
| 356 | posix.ENOSPC => PosixWriteError.NoSpaceLeft, | |
| 357 | posix.EPERM => PosixWriteError.AccessDenied, | |
| 358 | posix.EPIPE => PosixWriteError.BrokenPipe, | |
| 359 | else => unexpectedErrorPosix(write_err), | |
| 360 | }; | |
| 346 | switch (write_err) { | |
| 347 | 0 => { | |
| 348 | index += rc; | |
| 349 | continue; | |
| 350 | }, | |
| 351 | posix.EINTR => continue, | |
| 352 | posix.EINVAL => unreachable, | |
| 353 | posix.EFAULT => unreachable, | |
| 354 | posix.EAGAIN => return PosixWriteError.WouldBlock, | |
| 355 | posix.EBADF => return PosixWriteError.FileClosed, | |
| 356 | posix.EDESTADDRREQ => return PosixWriteError.DestinationAddressRequired, | |
| 357 | posix.EDQUOT => return PosixWriteError.DiskQuota, | |
| 358 | posix.EFBIG => return PosixWriteError.FileTooBig, | |
| 359 | posix.EIO => return PosixWriteError.InputOutput, | |
| 360 | posix.ENOSPC => return PosixWriteError.NoSpaceLeft, | |
| 361 | posix.EPERM => return PosixWriteError.AccessDenied, | |
| 362 | posix.EPIPE => return PosixWriteError.BrokenPipe, | |
| 363 | else => return unexpectedErrorPosix(write_err), | |
| 361 | 364 | } |
| 362 | index += rc; | |
| 363 | 365 | } |
| 364 | 366 | } |
| 365 | 367 | |
| ... | ... | @@ -1614,7 +1616,7 @@ pub const Dir = struct { |
| 1614 | 1616 | return null; |
| 1615 | 1617 | } |
| 1616 | 1618 | const name_utf16le = mem.toSlice(u16, self.handle.find_file_data.cFileName[0..].ptr); |
| 1617 | if (mem.eql(u16, name_utf16le, []u16{'.'}) or mem.eql(u16, name_utf16le, []u16{'.', '.'})) | |
| 1619 | if (mem.eql(u16, name_utf16le, []u16{'.'}) or mem.eql(u16, name_utf16le, []u16{ '.', '.' })) | |
| 1618 | 1620 | continue; |
| 1619 | 1621 | // Trust that Windows gives us valid UTF-16LE |
| 1620 | 1622 | const name_utf8_len = std.unicode.utf16leToUtf8(self.handle.name_data[0..], name_utf16le) catch unreachable; |
test/behavior.zig+1| ... | ... | @@ -12,6 +12,7 @@ comptime { |
| 12 | 12 | _ = @import("cases/bugs/1277.zig"); |
| 13 | 13 | _ = @import("cases/bugs/1381.zig"); |
| 14 | 14 | _ = @import("cases/bugs/1421.zig"); |
| 15 | _ = @import("cases/bugs/1442.zig"); | |
| 15 | 16 | _ = @import("cases/bugs/394.zig"); |
| 16 | 17 | _ = @import("cases/bugs/655.zig"); |
| 17 | 18 | _ = @import("cases/bugs/656.zig"); |
test/cases/bugs/1442.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const Union = union(enum) { | |
| 4 | Text: []const u8, | |
| 5 | Color: u32, | |
| 6 | }; | |
| 7 | ||
| 8 | test "const error union field alignment" { | |
| 9 | var union_or_err: error!Union = Union{ .Color = 1234 }; | |
| 10 | std.debug.assertOrPanic((union_or_err catch unreachable).Color == 1234); | |
| 11 | } |