From 01573658729e212bad1c9dc506cd0666682488fb Mon Sep 17 00:00:00 2001 From: Euan Torano Date: Mon, 5 Aug 2019 16:07:52 +0100 Subject: [PATCH 01/16] Add missing S_IS* for NetBSD --- std/os/bits/netbsd.zig | 59 ++++++++++++++++++++++++++++++++++++++++++ std/os/netbsd.zig | 1 + 2 files changed, 60 insertions(+) diff --git a/std/os/bits/netbsd.zig b/std/os/bits/netbsd.zig index ef58bd1356..ff19d090af 100644 --- a/std/os/bits/netbsd.zig +++ b/std/os/bits/netbsd.zig @@ -760,3 +760,62 @@ pub const stack_t = extern struct { ss_size: isize, ss_flags: i32, }; + +pub const S_IFMT = 0o170000; + +pub const S_IFIFO = 0o010000; +pub const S_IFCHR = 0o020000; +pub const S_IFDIR = 0o040000; +pub const S_IFBLK = 0o060000; +pub const S_IFREG = 0o100000; +pub const S_IFLNK = 0o120000; +pub const S_IFSOCK = 0o140000; +pub const S_IFWHT = 0o160000; + +pub const S_ISUID = 0o4000; +pub const S_ISGID = 0o2000; +pub const S_ISVTX = 0o1000; +pub const S_IRWXU = 0o700; +pub const S_IRUSR = 0o400; +pub const S_IWUSR = 0o200; +pub const S_IXUSR = 0o100; +pub const S_IRWXG = 0o070; +pub const S_IRGRP = 0o040; +pub const S_IWGRP = 0o020; +pub const S_IXGRP = 0o010; +pub const S_IRWXO = 0o007; +pub const S_IROTH = 0o004; +pub const S_IWOTH = 0o002; +pub const S_IXOTH = 0o001; + +pub fn S_ISFIFO(m: u32) bool { + return m & S_IFMT == S_IFIFO; +} + +pub fn S_ISCHR(m: u32) bool { + return m & S_IFMT == S_IFCHR; +} + +pub fn S_ISDIR(m: u32) bool { + return m & S_IFMT == S_IFDIR; +} + +pub fn S_ISBLK(m: u32) bool { + return m & S_IFMT == S_IFBLK; +} + +pub fn S_ISREG(m: u32) bool { + return m & S_IFMT == S_IFREG; +} + +pub fn S_ISLNK(m: u32) bool { + return m & S_IFMT == S_IFLNK; +} + +pub fn S_ISSOCK(m: u32) bool { + return m & S_IFMT == S_IFSOCK; +} + +pub fn S_IWHT(m: u32) bool { + return m & S_IFMT == S_IFWHT; +} diff --git a/std/os/netbsd.zig b/std/os/netbsd.zig index cd63e40f5c..802283fc87 100644 --- a/std/os/netbsd.zig +++ b/std/os/netbsd.zig @@ -2,3 +2,4 @@ const builtin = @import("builtin"); const std = @import("../std.zig"); pub const is_the_target = builtin.os == .netbsd; pub usingnamespace std.c; +pub usingnamespace @import("bits.zig"); \ No newline at end of file From 8aa87ec441c13ce590dc5a9f48aab638326c8b67 Mon Sep 17 00:00:00 2001 From: Euan T Date: Mon, 5 Aug 2019 16:35:40 +0100 Subject: [PATCH 02/16] Add misisng newline --- std/os/netbsd.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/os/netbsd.zig b/std/os/netbsd.zig index 802283fc87..d484e7374b 100644 --- a/std/os/netbsd.zig +++ b/std/os/netbsd.zig @@ -2,4 +2,4 @@ const builtin = @import("builtin"); const std = @import("../std.zig"); pub const is_the_target = builtin.os == .netbsd; pub usingnamespace std.c; -pub usingnamespace @import("bits.zig"); \ No newline at end of file +pub usingnamespace @import("bits.zig"); From 7b8c96612f1326525c655abe7f7bb0472cbddee1 Mon Sep 17 00:00:00 2001 From: Euan Torano Date: Mon, 5 Aug 2019 17:21:12 +0100 Subject: [PATCH 03/16] Fix #2993 - use getrandom on freebsd --- std/c/freebsd.zig | 1 + std/os.zig | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index bcc60e65ed..3d5736d37b 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -6,3 +6,4 @@ pub const _errno = __error; pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; +pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int; diff --git a/std/os.zig b/std/os.zig index c2010bf6a9..805f7f1645 100644 --- a/std/os.zig +++ b/std/os.zig @@ -120,6 +120,19 @@ pub fn getrandom(buf: []u8) GetRandomError!void { } } } + if (freebsd.is_the_target) { + while (true) { + const err = std.c.getErrno(std.c.getrandom(buf.ptr, buf.len, 0)); + + switch (err) { + 0 => return, + EINVAL => unreachable, + EFAULT => unreachable, + EINTR => continue, + else => return unexpectedErrno(err), + } + } + } if (wasi.is_the_target) { switch (wasi.random_get(buf.ptr, buf.len)) { 0 => return, From 7f23dac6dce2ce897295e8186f164f695cacdbc9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 5 Aug 2019 13:49:17 -0400 Subject: [PATCH 04/16] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91178f87de..1be33c34f7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![ZIG](https://ziglang.org/zig-logo.svg) -Zig is an open-source programming language designed for **robustness**, +A general-purpose programming language designed for **robustness**, **optimality**, and **maintainability**. ## Resources From 2d25348f63691921d54e12ae938f185ac96e4cf6 Mon Sep 17 00:00:00 2001 From: Euan Torano Date: Tue, 6 Aug 2019 19:32:22 +0100 Subject: [PATCH 05/16] Fix function signature and use a loop to ensure buffer is filled. --- std/os/windows.zig | 15 ++++++++++++--- std/os/windows/advapi32.zig | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/std/os/windows.zig b/std/os/windows.zig index ac76e8f58f..a8f5b54644 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -138,10 +138,19 @@ pub const RtlGenRandomError = error{Unexpected}; /// https://github.com/rust-lang-nursery/rand/issues/111 /// https://bugzilla.mozilla.org/show_bug.cgi?id=504270 pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void { - if (advapi32.RtlGenRandom(output.ptr, output.len) == 0) { - switch (kernel32.GetLastError()) { - else => |err| return unexpectedError(err), + var total_read: usize = 0; + var buff: []u8 = output[0..]; + const max_read_size: ULONG = ULONG(maxInt(ULONG)); + + while (total_read < output.len) { + const to_read: ULONG = @intCast(ULONG, math.min(buff.len, max_read_size)); + + if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) { + return unexpectedError(kernel32.GetLastError()); } + + total_read += @intCast(usize, to_read); + buff = buff[to_read..]; } } diff --git a/std/os/windows/advapi32.zig b/std/os/windows/advapi32.zig index 165a2c10a3..940f10994c 100644 --- a/std/os/windows/advapi32.zig +++ b/std/os/windows/advapi32.zig @@ -19,5 +19,5 @@ pub extern "advapi32" stdcallcc fn RegQueryValueExW( // RtlGenRandom is known as SystemFunction036 under advapi32 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ -pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: usize) BOOL; +pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL; pub const RtlGenRandom = SystemFunction036; From 8fcf21fefce56695820b5ec31161589822df8762 Mon Sep 17 00:00:00 2001 From: Ryan Saunderson Date: Wed, 7 Aug 2019 12:51:30 -0500 Subject: [PATCH 06/16] modify header precedence for zig cc, resolves intrinsics issues (#3027) --- src/codegen.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index ef24716dff..881b83c169 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8292,15 +8292,18 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } } + //note(dimenus): appending libc headers before c_headers breaks intrinsics + //and other compiler specific items + // According to Rich Felker libc headers are supposed to go before C language headers. + args.append("-isystem"); + args.append(buf_ptr(g->zig_c_headers_dir)); + for (size_t i = 0; i < g->libc_include_dir_len; i += 1) { Buf *include_dir = g->libc_include_dir_list[i]; args.append("-isystem"); args.append(buf_ptr(include_dir)); } - // According to Rich Felker libc headers are supposed to go before C language headers. - args.append("-isystem"); - args.append(buf_ptr(g->zig_c_headers_dir)); if (g->zig_target->is_native) { args.append("-march=native"); From 2cd5e555818583e77e5601d43d55339e8c4017b0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 7 Aug 2019 16:27:58 -0400 Subject: [PATCH 07/16] std.math.min: return a more restrictive type sometimes --- std/math.zig | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/std/math.zig b/std/math.zig index ac06a07953..2745fe6508 100644 --- a/std/math.zig +++ b/std/math.zig @@ -242,12 +242,69 @@ pub fn floatExponentBits(comptime T: type) comptime_int { }; } -pub fn min(x: var, y: var) @typeOf(x + y) { - return if (x < y) x else y; +/// Given two types, returns the smallest one which is capable of holding the +/// full range of the minimum value. +pub fn Min(comptime A: type, comptime B: type) type { + return switch (@typeInfo(A)) { + .Int => |a_info| switch (@typeInfo(B)) { + .Int => |b_info| blk: { + if (a_info.is_signed == b_info.is_signed) { + break :blk if (a_info.bits < b_info.bits) A else B; + } else if (a_info.is_signed) { + break :blk A; + } else { + break :blk B; + } + }, + .ComptimeInt => A, + else => @compileError("unsupported type: " ++ @typeName(B)), + }, + .Float => |a_info| if (a_info.bits < @typeInfo(B).Float.bits) A else B, + .ComptimeInt => B, + .ComptimeFloat => B, + else => @compileError("unsupported type: " ++ @typeName(A)), + }; +} + +/// Returns the smaller number. When one of the parameter's type's full range fits in the other, +/// the return type is the smaller type. +pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { + const Result = Min(@typeOf(x), @typeOf(y)); + if (x < y) { + // TODO Zig should allow this as an implicit cast because x is immutable and in this + // scope it is known to fit in the return type. + switch (@typeInfo(Result)) { + .Int => return @intCast(Result, x), + .Float => return @floatCast(Result, x), + else => return x, + } + } else { + // TODO Zig should allow this as an implicit cast because y is immutable and in this + // scope it is known to fit in the return type. + switch (@typeInfo(Result)) { + .Int => return @intCast(Result, y), + .Float => return @floatCast(Result, y), + else => return y, + } + } } test "math.min" { testing.expect(min(i32(-1), i32(2)) == -1); + { + var a: u16 = 999; + var b: u32 = 10; + var result = min(a, b); + testing.expect(@typeOf(result) == u16); + testing.expect(result == 10); + } + { + var a: f64 = 10.34; + var b: f32 = 999.12; + var result = min(a, b); + testing.expect(@typeOf(result) == f32); + testing.expect(result == 10.34); + } } pub fn max(x: var, y: var) @typeOf(x + y) { From 8621e3b5bd814005129b58469d93c2499e3d085e Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Wed, 7 Aug 2019 11:51:12 +0100 Subject: [PATCH 08/16] Don't emit clang error if source or filename pointer is null --- src/ir.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 65a21a418d..2b096a3383 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -21312,12 +21312,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct } for (size_t i = 0; i < errors_len; i += 1) { Stage2ErrorMsg *clang_err = &errors_ptr[i]; - ErrorMsg *err_msg = err_msg_create_with_offset( - clang_err->filename_ptr ? - buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), - clang_err->line, clang_err->column, clang_err->offset, clang_err->source, - buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); - err_msg_add_note(parent_err_msg, err_msg); + // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null + if (clang_err->source && clang_err->filename_ptr) { + ErrorMsg *err_msg = err_msg_create_with_offset( + clang_err->filename_ptr ? + buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), + clang_err->line, clang_err->column, clang_err->offset, clang_err->source, + buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); + err_msg_add_note(parent_err_msg, err_msg); + } } return ira->codegen->invalid_instruction; From f2bef0447a523e6f21ab21e4845aa982a1332572 Mon Sep 17 00:00:00 2001 From: Euan Torano Date: Wed, 7 Aug 2019 22:19:25 +0100 Subject: [PATCH 09/16] Remove unneeded casts. --- std/os/windows.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/std/os/windows.zig b/std/os/windows.zig index a8f5b54644..4c6bfe70d5 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -140,16 +140,16 @@ pub const RtlGenRandomError = error{Unexpected}; pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void { var total_read: usize = 0; var buff: []u8 = output[0..]; - const max_read_size: ULONG = ULONG(maxInt(ULONG)); + const max_read_size: ULONG = maxInt(ULONG); while (total_read < output.len) { - const to_read: ULONG = @intCast(ULONG, math.min(buff.len, max_read_size)); + const to_read: ULONG = math.min(buff.len, max_read_size); if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) { return unexpectedError(kernel32.GetLastError()); } - total_read += @intCast(usize, to_read); + total_read += to_read; buff = buff[to_read..]; } } From 0bf6796b76501efef486815946ce12932d6f6a21 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 9 Aug 2019 10:22:02 -0400 Subject: [PATCH 10/16] fix regression in std.math.min closes #3035 --- std/math.zig | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/std/math.zig b/std/math.zig index 2745fe6508..73f981528c 100644 --- a/std/math.zig +++ b/std/math.zig @@ -245,25 +245,20 @@ pub fn floatExponentBits(comptime T: type) comptime_int { /// Given two types, returns the smallest one which is capable of holding the /// full range of the minimum value. pub fn Min(comptime A: type, comptime B: type) type { - return switch (@typeInfo(A)) { + switch (@typeInfo(A)) { .Int => |a_info| switch (@typeInfo(B)) { - .Int => |b_info| blk: { - if (a_info.is_signed == b_info.is_signed) { - break :blk if (a_info.bits < b_info.bits) A else B; - } else if (a_info.is_signed) { - break :blk A; + .Int => |b_info| if (!a_info.is_signed and !b_info.is_signed) { + if (a_info.bits < b_info.bits) { + return A; } else { - break :blk B; + return B; } }, - .ComptimeInt => A, - else => @compileError("unsupported type: " ++ @typeName(B)), + else => {}, }, - .Float => |a_info| if (a_info.bits < @typeInfo(B).Float.bits) A else B, - .ComptimeInt => B, - .ComptimeFloat => B, - else => @compileError("unsupported type: " ++ @typeName(A)), - }; + else => {}, + } + return @typeOf(A(0) + B(0)); } /// Returns the smaller number. When one of the parameter's type's full range fits in the other, @@ -275,7 +270,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { // scope it is known to fit in the return type. switch (@typeInfo(Result)) { .Int => return @intCast(Result, x), - .Float => return @floatCast(Result, x), else => return x, } } else { @@ -283,7 +277,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { // scope it is known to fit in the return type. switch (@typeInfo(Result)) { .Int => return @intCast(Result, y), - .Float => return @floatCast(Result, y), else => return y, } } @@ -302,9 +295,16 @@ test "math.min" { var a: f64 = 10.34; var b: f32 = 999.12; var result = min(a, b); - testing.expect(@typeOf(result) == f32); + testing.expect(@typeOf(result) == f64); testing.expect(result == 10.34); } + { + var a: i8 = -127; + var b: i16 = -200; + var result = min(a, b); + testing.expect(@typeOf(result) == i16); + testing.expect(result == -200); + } } pub fn max(x: var, y: var) @typeOf(x + y) { From e6ebc41a07b294e602f8594e001df78e143e190f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 9 Aug 2019 17:09:27 -0400 Subject: [PATCH 11/16] add a little compile error to make Future Andy's life easier --- tools/process_headers.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/process_headers.zig b/tools/process_headers.zig index f191721316..805fc3d5f7 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -504,6 +504,9 @@ const Contents = struct { } }; +comptime { + @compileError("the behavior of std.AutoHashMap changed and []const u8 will be treated as a pointer. will need to update the hash maps to actually do some kind of hashing on the slices."); +} const HashToContents = std.AutoHashMap([]const u8, Contents); const TargetToHash = std.HashMap(DestTarget, []const u8, DestTarget.hash, DestTarget.eql); const PathTable = std.AutoHashMap([]const u8, *TargetToHash); From 4bd4c5e06d13c35a70d0207b730fb67b83ff6363 Mon Sep 17 00:00:00 2001 From: data-man Date: Fri, 9 Aug 2019 12:43:29 +0500 Subject: [PATCH 12/16] Fixed tiny typo in the math module (shr's description) --- std/math.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/math.zig b/std/math.zig index 73f981528c..e10c9329d9 100644 --- a/std/math.zig +++ b/std/math.zig @@ -366,7 +366,7 @@ test "math.shl" { } /// Shifts right. Overflowed bits are truncated. -/// A negative shift amount results in a lefft shift. +/// A negative shift amount results in a left shift. pub fn shr(comptime T: type, a: T, shift_amt: var) T { const abs_shift_amt = absCast(shift_amt); const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt); From 1b83ee78a48a64bef28f12b7b2e263074f88b6b6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Aug 2019 12:00:32 -0400 Subject: [PATCH 13/16] allow comptime_int to implicit cast to comptime_float --- src/ir.cpp | 3 +++ std/math.zig | 7 +++++++ test/compile_errors.zig | 8 -------- test/stage1/behavior/cast.zig | 7 ++++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 2b096a3383..13348d28c4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9713,6 +9713,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); assert(const_val_is_int || const_val_is_float); + if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { + return true; + } if (other_type->id == ZigTypeIdFloat) { if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { return true; diff --git a/std/math.zig b/std/math.zig index e10c9329d9..e47021512e 100644 --- a/std/math.zig +++ b/std/math.zig @@ -305,6 +305,13 @@ test "math.min" { testing.expect(@typeOf(result) == i16); testing.expect(result == -200); } + { + const a = 10.34; + var b: f32 = 999.12; + var result = min(a, b); + testing.expect(@typeOf(result) == f32); + testing.expect(result == 10.34); + } } pub fn max(x: var, y: var) @typeOf(x + y) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index a4bc2a66f0..437e40900d 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3225,14 +3225,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:3:17: note: value 8 cannot fit into type u3", ); - cases.add( - "incompatible number literals", - \\const x = 2 == 2.0; - \\export fn entry() usize { return @sizeOf(@typeOf(x)); } - , - "tmp.zig:1:11: error: integer value 2 cannot be implicitly casted to type 'comptime_float'", - ); - cases.add( "missing function call param", \\const Foo = struct { diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index c243f18088..04c7fa606f 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -508,7 +508,7 @@ test "peer type resolution: unreachable, null, slice" { } test "peer type resolution: unreachable, error set, unreachable" { - const Error = error { + const Error = error{ FileDescriptorAlreadyPresentInSet, OperationCausesCircularLoop, FileDescriptorNotRegistered, @@ -529,3 +529,8 @@ test "peer type resolution: unreachable, error set, unreachable" { }; expect(transformed_err == error.SystemResources); } + +test "implicit cast comptime_int to comptime_float" { + comptime expect(comptime_float(10) == f32(10)); + expect(2 == 2.0); +} From b87686dfa094770e96da33fb23a7d011a168157c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Aug 2019 13:43:44 -0400 Subject: [PATCH 14/16] fix enum with one member and custom tag type --- src/ir.cpp | 1 - test/stage1/behavior/enum.zig | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index 13348d28c4..fde2b972f8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11938,7 +11938,6 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour if (enum_type->data.enumeration.layout == ContainerLayoutAuto && enum_type->data.enumeration.src_field_count == 1) { - assert(tag_type == ira->codegen->builtin_types.entry_num_lit_int); IrInstruction *result = ir_const(ira, source_instr, tag_type); init_const_bigint(&result->value, tag_type, &enum_type->data.enumeration.fields[0].value); diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig index 51f4f0e196..d7d34aec88 100644 --- a/test/stage1/behavior/enum.zig +++ b/test/stage1/behavior/enum.zig @@ -982,3 +982,14 @@ test "enum literal casting to tagged union" { else => @panic("fail"), } } + +test "enum with one member and custom tag type" { + const E = enum(u2) { + One, + }; + expect(@enumToInt(E.One) == 0); + const E2 = enum(u2) { + One = 2, + }; + expect(@enumToInt(E2.One) == 2); +} From 3aed7de0c47af40e6ca00c0e969ad30b44af5a7c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Aug 2019 16:09:23 -0400 Subject: [PATCH 15/16] README: link to community projects --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1be33c34f7..9cf0893da8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A general-purpose programming language designed for **robustness**, * [Community](https://github.com/ziglang/zig/wiki/Community) * [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md) * [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ) + * [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects) ## Building from Source From 98183e47436699f6e5eab200061c46eec342806e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 13 Aug 2019 11:33:01 -0400 Subject: [PATCH 16/16] flip the order of fields in error unions to prepare for fixing u128 alignment issues --- src/all_types.hpp | 4 ++-- src/analyze.cpp | 13 +++++++------ src/codegen.cpp | 25 ++++--------------------- 3 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 4c3aeade9e..e9d5aa3834 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3772,8 +3772,8 @@ static const size_t slice_len_index = 1; static const size_t maybe_child_index = 0; static const size_t maybe_null_index = 1; -static const size_t err_union_err_index = 0; -static const size_t err_union_payload_index = 1; +static const size_t err_union_payload_index = 0; +static const size_t err_union_err_index = 1; // TODO call graph analysis to find out what this number needs to be for every function // MUST BE A POWER OF TWO. diff --git a/src/analyze.cpp b/src/analyze.cpp index 0af1baec35..672e75a5ee 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -7017,20 +7017,21 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type); uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type); - ZigLLVMDIType *di_element_types[] = { - ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), + ZigLLVMDIType *di_element_types[2]; + di_element_types[err_union_err_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, + ZigLLVMTypeToScope(type->llvm_di_type), "tag", di_file, line, tag_debug_size_in_bits, tag_debug_align_in_bits, tag_offset_in_bits, - ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type)), - ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type)); + di_element_types[err_union_payload_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, + ZigLLVMTypeToScope(type->llvm_di_type), "value", di_file, line, value_debug_size_in_bits, value_debug_align_in_bits, value_offset_in_bits, - ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)), - }; + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)); ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, compile_unit_scope, diff --git a/src/codegen.cpp b/src/codegen.cpp index 881b83c169..32e6d2fbee 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6437,29 +6437,12 @@ 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(g, payload_val->type, err_payload_value); } + LLVMValueRef fields[2]; + fields[err_union_err_index] = err_tag_value; + fields[err_union_payload_index] = err_payload_value; if (make_unnamed_struct) { - uint64_t payload_off = LLVMOffsetOfElement(g->target_data_ref, get_llvm_type(g, type_entry), 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); - } + return LLVMConstStruct(fields, 2, false); } else { - LLVMValueRef fields[] = { - err_tag_value, - err_payload_value, - }; return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2); } }