mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 15:12:31 +00:00
Compare commits
13 Commits
e9e6ae8de7
...
f04c3cad69
Author | SHA1 | Date | |
---|---|---|---|
|
f04c3cad69 | ||
|
87863a834b | ||
|
b0dcce93f7 | ||
|
f6392b9526 | ||
|
21f0fce28b | ||
|
775b48dd10 | ||
|
aa5341bf85 | ||
|
da0eb66b67 | ||
|
990588eb76 | ||
|
a5d6c6e16c | ||
|
44c1e35c14 | ||
|
adabfa2c9d | ||
|
57313b789e |
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
- name: Build and Test
|
||||
run: sh ci/aarch64-linux-release.sh
|
||||
x86_64-macos-release:
|
||||
runs-on: "macos-12"
|
||||
runs-on: "macos-13"
|
||||
env:
|
||||
ARCH: "x86_64"
|
||||
steps:
|
||||
|
@ -89,12 +89,7 @@ set(ZIG_SHARED_LLVM off CACHE BOOL "Prefer linking against shared LLVM libraries
|
||||
set(ZIG_STATIC_LLVM ${ZIG_STATIC} CACHE BOOL "Prefer linking against static LLVM libraries")
|
||||
set(ZIG_STATIC_ZLIB ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zlib")
|
||||
set(ZIG_STATIC_ZSTD ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zstd")
|
||||
if(APPLE AND ZIG_STATIC)
|
||||
set(ZIG_STATIC_CURSES on)
|
||||
else()
|
||||
set(ZIG_STATIC_CURSES off)
|
||||
endif()
|
||||
set(ZIG_STATIC_CURSES ${ZIG_STATIC_CURSES} CACHE BOOL "Prefer linking against static curses")
|
||||
set(ZIG_STATIC_CURSES OFF CACHE BOOL "Enable static linking against curses")
|
||||
|
||||
if (ZIG_SHARED_LLVM AND ZIG_STATIC_LLVM)
|
||||
message(SEND_ERROR "-DZIG_SHARED_LLVM and -DZIG_STATIC_LLVM cannot both be enabled simultaneously")
|
||||
|
@ -531,7 +531,7 @@ pub const Os = struct {
|
||||
},
|
||||
.macos => .{
|
||||
.semver = .{
|
||||
.min = .{ .major = 11, .minor = 7, .patch = 1 },
|
||||
.min = .{ .major = 13, .minor = 0, .patch = 0 },
|
||||
.max = .{ .major = 15, .minor = 2, .patch = 0 },
|
||||
},
|
||||
},
|
||||
|
@ -646,7 +646,10 @@ pub fn Poller(comptime StreamEnum: type) type {
|
||||
// always check if there's some data waiting to be read first.
|
||||
if (poll_fd.revents & posix.POLL.IN != 0) {
|
||||
const buf = try q.writableWithSize(bump_amt);
|
||||
const amt = try posix.read(poll_fd.fd, buf);
|
||||
const amt = posix.read(poll_fd.fd, buf) catch |err| switch (err) {
|
||||
error.BrokenPipe => 0, // Handle the same as EOF.
|
||||
else => |e| return e,
|
||||
};
|
||||
q.update(amt);
|
||||
if (amt == 0) {
|
||||
// Remove the fd when the EOF condition is met.
|
||||
|
@ -115,6 +115,10 @@ pub fn Complex(comptime T: type) type {
|
||||
pub fn magnitude(self: Self) T {
|
||||
return @sqrt(self.re * self.re + self.im * self.im);
|
||||
}
|
||||
|
||||
pub fn squaredMagnitude(self: Self) T {
|
||||
return self.re * self.re + self.im * self.im;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -189,6 +193,13 @@ test "magnitude" {
|
||||
try testing.expect(math.approxEqAbs(f32, c, 5.83095, epsilon));
|
||||
}
|
||||
|
||||
test "squaredMagnitude" {
|
||||
const a = Complex(f32).init(5, 3);
|
||||
const c = a.squaredMagnitude();
|
||||
|
||||
try testing.expect(math.approxEqAbs(f32, c, math.pow(f32, a.magnitude(), 2), epsilon));
|
||||
}
|
||||
|
||||
test {
|
||||
_ = @import("complex/abs.zig");
|
||||
_ = @import("complex/acosh.zig");
|
||||
|
@ -293,19 +293,16 @@ pub fn killPosix(self: *ChildProcess) !Term {
|
||||
error.ProcessNotFound => return error.AlreadyTerminated,
|
||||
else => return err,
|
||||
};
|
||||
try self.waitUnwrapped();
|
||||
self.waitUnwrapped();
|
||||
return self.term.?;
|
||||
}
|
||||
|
||||
pub const WaitError = SpawnError || std.os.windows.GetProcessMemoryInfoError;
|
||||
|
||||
/// Blocks until child process terminates and then cleans up all resources.
|
||||
pub fn wait(self: *ChildProcess) !Term {
|
||||
const term = if (native_os == .windows)
|
||||
try self.waitWindows()
|
||||
else
|
||||
try self.waitPosix();
|
||||
|
||||
pub fn wait(self: *ChildProcess) WaitError!Term {
|
||||
const term = if (native_os == .windows) try self.waitWindows() else self.waitPosix();
|
||||
self.id = undefined;
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
@ -408,7 +405,7 @@ pub fn run(args: struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn waitWindows(self: *ChildProcess) !Term {
|
||||
fn waitWindows(self: *ChildProcess) WaitError!Term {
|
||||
if (self.term) |term| {
|
||||
self.cleanupStreams();
|
||||
return term;
|
||||
@ -418,17 +415,17 @@ fn waitWindows(self: *ChildProcess) !Term {
|
||||
return self.term.?;
|
||||
}
|
||||
|
||||
fn waitPosix(self: *ChildProcess) !Term {
|
||||
fn waitPosix(self: *ChildProcess) SpawnError!Term {
|
||||
if (self.term) |term| {
|
||||
self.cleanupStreams();
|
||||
return term;
|
||||
}
|
||||
|
||||
try self.waitUnwrapped();
|
||||
self.waitUnwrapped();
|
||||
return self.term.?;
|
||||
}
|
||||
|
||||
fn waitUnwrappedWindows(self: *ChildProcess) !void {
|
||||
fn waitUnwrappedWindows(self: *ChildProcess) WaitError!void {
|
||||
const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false);
|
||||
|
||||
self.term = @as(SpawnError!Term, x: {
|
||||
@ -450,7 +447,7 @@ fn waitUnwrappedWindows(self: *ChildProcess) !void {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn waitUnwrapped(self: *ChildProcess) !void {
|
||||
fn waitUnwrapped(self: *ChildProcess) void {
|
||||
const res: posix.WaitPidResult = res: {
|
||||
if (self.request_resource_usage_statistics) {
|
||||
switch (native_os) {
|
||||
|
56
src/Sema.zig
56
src/Sema.zig
@ -9092,11 +9092,57 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||
const result = try block.addTyOp(.intcast, dest_ty, operand);
|
||||
if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum(zcu) and
|
||||
zcu.backendSupportsFeature(.is_named_enum_value))
|
||||
{
|
||||
const ok = try block.addUnOp(.is_named_enum_value, result);
|
||||
try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
|
||||
if (block.wantSafety()) {
|
||||
if (dest_ty.isNonexhaustiveEnum(zcu)) {
|
||||
// these checks are similar to those generated by `intCast`,
|
||||
// except that `invalid_enum_value` is the panic reason for all
|
||||
// failures.
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
const operand_int_info = sema.typeOf(operand).intInfo(zcu);
|
||||
const dest_tag_ty = dest_ty.intTagType(zcu);
|
||||
const dest_int_info = dest_tag_ty.intInfo(zcu);
|
||||
var ok: ?Air.Inst.Ref = null;
|
||||
if (operand_int_info.bits > dest_int_info.bits) {
|
||||
// narrowing cast; operand <= dest_max_int required, and operand >= 0 may be
|
||||
// required if operand is signed and destination int is unsigned
|
||||
const dest_max_int = Air.internedToRef((try dest_tag_ty.maxIntScalar(pt, operand_ty)).toIntern());
|
||||
// operand <= maxInt(dest_tag_ty)
|
||||
const le_check = try block.addBinOp(.cmp_lte, operand, dest_max_int);
|
||||
if (operand_int_info.signedness == .signed) {
|
||||
const dest_min_int = Air.internedToRef((try dest_tag_ty.minIntScalar(pt, operand_ty)).toIntern());
|
||||
const ge_zero_check = try block.addBinOp(.cmp_gte, operand, dest_min_int);
|
||||
// operand >= minInt(dest_tag_ty) and operand <= maxInt(dest_tag_ty)
|
||||
ok = try block.addBinOp(.bool_and, le_check, ge_zero_check);
|
||||
} else {
|
||||
ok = le_check;
|
||||
}
|
||||
} else if (operand_int_info.bits == dest_int_info.bits) {
|
||||
// checks are only needed here if the operand type's sign differs
|
||||
// from the destination type's tag's sign.
|
||||
if (operand_int_info.signedness == .unsigned and dest_int_info.signedness == .signed) {
|
||||
const dest_max_int = try dest_tag_ty.maxIntScalar(pt, operand_ty);
|
||||
// operand <= maxInt(dest_tag_ty)
|
||||
ok = try block.addBinOp(.cmp_lte, operand, Air.internedToRef(dest_max_int.toIntern()));
|
||||
} else if (operand_int_info.signedness == .signed and dest_int_info.signedness == .unsigned) {
|
||||
const zero = try pt.intValue_i64(operand_ty, 0);
|
||||
// operand >= 0
|
||||
ok = try block.addBinOp(.cmp_gte, operand, Air.internedToRef(zero.toIntern()));
|
||||
} // else => operand and destination int are the same type; no checks needed
|
||||
} else {
|
||||
// extending cast; no checks needed unless the operand is signed
|
||||
// and the destination is unsigned
|
||||
if (operand_int_info.signedness == .signed and dest_int_info.signedness == .unsigned) {
|
||||
const zero = try pt.intValue_i64(operand_ty, 0);
|
||||
// operand >= 0
|
||||
ok = try block.addBinOp(.cmp_gte, operand, Air.internedToRef(zero.toIntern()));
|
||||
}
|
||||
}
|
||||
if (ok) |check|
|
||||
try sema.addSafetyCheck(block, src, check, .invalid_enum_value);
|
||||
} else if (zcu.backendSupportsFeature(.is_named_enum_value)) {
|
||||
const ok = try block.addUnOp(.is_named_enum_value, result);
|
||||
try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
const std = @import("std");
|
||||
|
||||
const SignedWithVariants = enum(i4) { a, b, _ };
|
||||
|
||||
const UnsignedWithVariants = enum(u4) { a, b, _ };
|
||||
|
||||
const SignedEmpty = enum(i6) { _ };
|
||||
|
||||
const UnsignedEmpty = enum(u6) { _ };
|
||||
|
||||
pub fn main() void {
|
||||
inline for (.{ SignedWithVariants, UnsignedWithVariants, SignedEmpty, UnsignedEmpty }) |EnumTy| {
|
||||
const TagType = @typeInfo(EnumTy).@"enum".tag_type;
|
||||
var v: isize = std.math.minInt(TagType);
|
||||
while (v < std.math.maxInt(TagType)) : (v += 1) {
|
||||
const variant = @as(EnumTy, @enumFromInt(v));
|
||||
assert(@as(@TypeOf(v), @intCast(@intFromEnum(variant))) == v);
|
||||
}
|
||||
const max = std.math.maxInt(TagType);
|
||||
const max_variant = @as(EnumTy, @enumFromInt(max));
|
||||
assert(@as(@TypeOf(max), @intCast(@intFromEnum(max_variant))) == max);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert(ok: bool) void {
|
||||
if (!ok) unreachable;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage2,llvm
|
@ -0,0 +1,20 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
if (std.mem.eql(u8, message, "invalid enum value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
const E = enum(u4) { _ };
|
||||
var invalid: u16 = 16;
|
||||
_ = &invalid;
|
||||
_ = @as(E, @enumFromInt(invalid));
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// target=native
|
Loading…
Reference in New Issue
Block a user