Compare commits

...

13 Commits

Author SHA1 Message Date
gabeuehlein
f04c3cad69
Merge da0eb66b67 into 87863a834b 2024-11-26 14:12:11 +01:00
Chris Boesch
87863a834b
std.math.complex: Add squared magnitude function (#21998)
Some checks are pending
ci / x86_64-linux-debug (push) Waiting to run
ci / x86_64-linux-release (push) Waiting to run
ci / aarch64-linux-debug (push) Waiting to run
ci / aarch64-linux-release (push) Waiting to run
ci / x86_64-macos-release (push) Waiting to run
ci / aarch64-macos-debug (push) Waiting to run
ci / aarch64-macos-release (push) Waiting to run
ci / x86_64-windows-debug (push) Waiting to run
ci / x86_64-windows-release (push) Waiting to run
ci / aarch64-windows (push) Waiting to run
2024-11-26 13:03:48 +00:00
Andrew Kelley
b0dcce93f7
Merge pull request #22075 from ziglang/fix-broken-pipe
Some checks are pending
ci / x86_64-linux-debug (push) Waiting to run
ci / x86_64-linux-release (push) Waiting to run
ci / aarch64-linux-debug (push) Waiting to run
ci / aarch64-linux-release (push) Waiting to run
ci / x86_64-macos-release (push) Waiting to run
ci / aarch64-macos-debug (push) Waiting to run
ci / aarch64-macos-release (push) Waiting to run
ci / x86_64-windows-debug (push) Waiting to run
ci / x86_64-windows-release (push) Waiting to run
ci / aarch64-windows (push) Waiting to run
std.io.Poller: handle EPIPE as EOF
2024-11-26 00:36:33 -05:00
Andrew Kelley
f6392b9526 cmake: don't add an unnecessary curses static lib dependency 2024-11-25 15:05:42 -08:00
Andrew Kelley
21f0fce28b CI: update macOS runner to 13
Apple has already dropped support for macOS 12.
GitHub Actions is dropping macOS 12 support now.
The Zig project is also dropping macOS 12 support now.

This commit also bumps default minimum macos version to 13.
2024-11-25 15:00:10 -08:00
Andrew Kelley
775b48dd10 std.io.Poller: handle EPIPE as EOF
closes #17483
2024-11-25 14:18:55 -08:00
Andrew Kelley
aa5341bf85 std.process.Child: explicit error set for wait 2024-11-25 14:18:55 -08:00
gabeuehlein
da0eb66b67
Merge branch 'master' into issue-21946 2024-11-25 16:34:30 -05:00
Gabriel Uehlein
990588eb76
Remove stage2 testing of invalid_nonexhaustive_enum_integer_value.zig
This makes this test like the other safety tests, as they don't test stage2
2024-11-24 23:20:11 -05:00
Gabriel Uehlein
a5d6c6e16c
Add target=native to invalid_nonexhaustive_enum_integer_value.zig
Selfhosted WASM turns panic into unreachable (I think?) so this commit disables testing stage2
2024-11-24 23:10:52 -05:00
Gabriel Uehlein
44c1e35c14
Safer (in the compiler) checks + don't use doNotOptimizeAway in safety test 2024-11-24 14:47:29 -05:00
Gabriel Uehlein
adabfa2c9d
Remove comptime_int check in zirEnumFromInt 2024-11-23 14:01:39 -05:00
Gabriel Uehlein
57313b789e
Make @enumFromInt do range checks on non-exhaustive enums' tag types
Fixes #21946
2024-11-23 13:54:57 -05:00
9 changed files with 129 additions and 27 deletions

View File

@ -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:

View File

@ -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")

View File

@ -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 },
},
},

View File

@ -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.

View File

@ -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");

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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