Commit 7dd3c3814d
Changed files (5)
src/analyze.cpp
@@ -5882,12 +5882,23 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
}
case ZigTypeIdErrorUnion:
{
- buf_appendf(buf, "(error union %s constant)", buf_ptr(&type_entry->name));
+ buf_appendf(buf, "%s(", buf_ptr(&type_entry->name));
+ if (const_val->data.x_err_union.err == nullptr) {
+ render_const_value(g, buf, const_val->data.x_err_union.payload);
+ } else {
+ buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->data.error_union.err_set_type->name),
+ buf_ptr(&const_val->data.x_err_union.err->name));
+ }
+ buf_appendf(buf, ")");
return;
}
case ZigTypeIdUnion:
{
- buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name));
+ uint64_t tag = bigint_as_unsigned(&const_val->data.x_union.tag);
+ TypeUnionField *field = &type_entry->data.unionation.fields[tag];
+ buf_appendf(buf, "%s { .%s = ", buf_ptr(&type_entry->name), buf_ptr(field->name));
+ render_const_value(g, buf, const_val->data.x_union.payload);
+ buf_append_str(buf, "}");
return;
}
case ZigTypeIdErrorSet:
src/codegen.cpp
@@ -5870,13 +5870,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
if (make_unnamed_struct) {
LLVMValueRef result = LLVMConstStruct(fields, 2, false);
- size_t expected_sz = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
- size_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result));
- if (actual_sz < expected_sz) {
- unsigned pad_sz = expected_sz - actual_sz;
+ uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1);
+ uint64_t end_offset = last_field_offset +
+ LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1]));
+ uint64_t expected_sz = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
+ unsigned pad_sz = expected_sz - end_offset;
+ if (pad_sz != 0) {
fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz));
result = LLVMConstStruct(fields, 3, false);
}
+ uint64_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result));
+ assert(actual_sz == expected_sz);
return result;
} else {
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
@@ -5917,13 +5921,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
err_payload_value = gen_const_val(g, payload_val, "");
make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value);
}
- LLVMValueRef fields[] = {
- err_tag_value,
- err_payload_value,
- };
if (make_unnamed_struct) {
- return LLVMConstStruct(fields, 2, false);
+ uint64_t payload_off = LLVMOffsetOfElement(g->target_data_ref, type_entry->type_ref, 1);
+ uint64_t err_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(err_tag_value));
+ unsigned pad_sz = payload_off - err_sz;
+ if (pad_sz == 0) {
+ LLVMValueRef fields[] = {
+ err_tag_value,
+ err_payload_value,
+ };
+ return LLVMConstStruct(fields, 2, false);
+ } else {
+ LLVMValueRef fields[] = {
+ err_tag_value,
+ LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)),
+ err_payload_value,
+ };
+ return LLVMConstStruct(fields, 3, false);
+ }
} else {
+ LLVMValueRef fields[] = {
+ err_tag_value,
+ err_payload_value,
+ };
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
}
}
std/os/index.zig
@@ -343,23 +343,25 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {
const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len));
const rc = posix.write(fd, bytes.ptr + index, amt_to_write);
const write_err = posix.getErrno(rc);
- if (write_err > 0) {
- return switch (write_err) {
- posix.EINTR => continue,
- posix.EINVAL, posix.EFAULT => unreachable,
- posix.EAGAIN => PosixWriteError.WouldBlock,
- posix.EBADF => PosixWriteError.FileClosed,
- posix.EDESTADDRREQ => PosixWriteError.DestinationAddressRequired,
- posix.EDQUOT => PosixWriteError.DiskQuota,
- posix.EFBIG => PosixWriteError.FileTooBig,
- posix.EIO => PosixWriteError.InputOutput,
- posix.ENOSPC => PosixWriteError.NoSpaceLeft,
- posix.EPERM => PosixWriteError.AccessDenied,
- posix.EPIPE => PosixWriteError.BrokenPipe,
- else => unexpectedErrorPosix(write_err),
- };
+ switch (write_err) {
+ 0 => {
+ index += rc;
+ continue;
+ },
+ posix.EINTR => continue,
+ posix.EINVAL => unreachable,
+ posix.EFAULT => unreachable,
+ posix.EAGAIN => return PosixWriteError.WouldBlock,
+ posix.EBADF => return PosixWriteError.FileClosed,
+ posix.EDESTADDRREQ => return PosixWriteError.DestinationAddressRequired,
+ posix.EDQUOT => return PosixWriteError.DiskQuota,
+ posix.EFBIG => return PosixWriteError.FileTooBig,
+ posix.EIO => return PosixWriteError.InputOutput,
+ posix.ENOSPC => return PosixWriteError.NoSpaceLeft,
+ posix.EPERM => return PosixWriteError.AccessDenied,
+ posix.EPIPE => return PosixWriteError.BrokenPipe,
+ else => return unexpectedErrorPosix(write_err),
}
- index += rc;
}
}
@@ -1614,7 +1616,7 @@ pub const Dir = struct {
return null;
}
const name_utf16le = mem.toSlice(u16, self.handle.find_file_data.cFileName[0..].ptr);
- if (mem.eql(u16, name_utf16le, []u16{'.'}) or mem.eql(u16, name_utf16le, []u16{'.', '.'}))
+ if (mem.eql(u16, name_utf16le, []u16{'.'}) or mem.eql(u16, name_utf16le, []u16{ '.', '.' }))
continue;
// Trust that Windows gives us valid UTF-16LE
const name_utf8_len = std.unicode.utf16leToUtf8(self.handle.name_data[0..], name_utf16le) catch unreachable;
test/cases/bugs/1442.zig
@@ -0,0 +1,11 @@
+const std = @import("std");
+
+const Union = union(enum) {
+ Text: []const u8,
+ Color: u32,
+};
+
+test "const error union field alignment" {
+ var union_or_err: error!Union = Union{ .Color = 1234 };
+ std.debug.assertOrPanic((union_or_err catch unreachable).Color == 1234);
+}
test/behavior.zig
@@ -12,6 +12,7 @@ comptime {
_ = @import("cases/bugs/1277.zig");
_ = @import("cases/bugs/1381.zig");
_ = @import("cases/bugs/1421.zig");
+ _ = @import("cases/bugs/1442.zig");
_ = @import("cases/bugs/394.zig");
_ = @import("cases/bugs/655.zig");
_ = @import("cases/bugs/656.zig");