@zigc/lib 0.15.1 → 0.15.2-test.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +19 -0
  2. package/build-web/fuzz.zig +6 -6
  3. package/build-web/time_report.zig +14 -13
  4. package/compiler/reduce/Walk.zig +10 -9
  5. package/compiler/reduce.zig +19 -20
  6. package/compiler/resinator/compile.zig +1 -1
  7. package/compiler_rt/arm.zig +1 -1
  8. package/init/build.zig +1 -1
  9. package/libc/include/generic-glibc/arpa/inet.h +3 -0
  10. package/libc/musl/src/fenv/loongarch64/fenv-sf.c +3 -0
  11. package/package.json +1 -1
  12. package/std/Build/Step/Compile.zig +20 -1
  13. package/std/Build/Step/TranslateC.zig +6 -0
  14. package/std/Build/WebServer.zig +1 -1
  15. package/std/Build.zig +4 -1
  16. package/std/Io/Reader/Limited.zig +44 -0
  17. package/std/Io/Reader.zig +128 -28
  18. package/std/Io/Writer.zig +31 -6
  19. package/std/Target.zig +8 -0
  20. package/std/Thread.zig +3 -4
  21. package/std/c.zig +87 -26
  22. package/std/crypto/aes_ocb.zig +32 -3
  23. package/std/crypto/tls/Client.zig +19 -8
  24. package/std/debug.zig +1 -1
  25. package/std/fs/Dir.zig +2 -1
  26. package/std/fs/File.zig +105 -104
  27. package/std/http/Client.zig +3 -2
  28. package/std/json/static.zig +3 -3
  29. package/std/math/big/int.zig +3 -4
  30. package/std/math/powi.zig +1 -0
  31. package/std/mem/Allocator.zig +3 -1
  32. package/std/mem.zig +3 -1
  33. package/std/net.zig +3 -2
  34. package/std/os/linux/bpf.zig +2 -2
  35. package/std/os/linux/powerpc.zig +74 -12
  36. package/std/os/linux/powerpc64.zig +74 -12
  37. package/std/os/linux.zig +7 -2
  38. package/std/os/uefi/protocol/service_binding.zig +1 -1
  39. package/std/os/uefi/tables.zig +1 -1
  40. package/std/pie.zig +1 -1
  41. package/std/posix.zig +6 -4
  42. package/std/process/Child.zig +5 -1
  43. package/std/process.zig +16 -2
  44. package/std/sort/pdq.zig +48 -1
  45. package/std/testing.zig +60 -0
  46. package/std/zig/llvm/BitcodeReader.zig +5 -1
  47. package/std/zig/system/linux.zig +1 -4
  48. package/std/zig/system.zig +3 -2
  49. package/std/zon/parse.zig +1 -0
  50. package/ubsan_rt.zig +3 -3
@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;
15
15
  const timespec = linux.timespec;
16
16
 
17
17
  pub fn syscall0(number: SYS) usize {
18
+ // r0 is both an input register and a clobber. musl and glibc achieve this with
19
+ // a "+" constraint, which isn't supported in Zig, so instead we separately list
20
+ // r0 as both an input and an output. (Listing it as an input and a clobber would
21
+ // cause the C backend to emit invalid code; see #25209.)
22
+ var r0_out: usize = undefined;
18
23
  return asm volatile (
19
24
  \\ sc
20
25
  \\ bns+ 1f
21
26
  \\ neg 3, 3
22
27
  \\ 1:
23
28
  : [ret] "={r3}" (-> usize),
29
+ [r0_out] "={r0}" (r0_out),
24
30
  : [number] "{r0}" (@intFromEnum(number)),
25
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
31
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
26
32
  }
27
33
 
28
34
  pub fn syscall1(number: SYS, arg1: usize) usize {
35
+ // r0 is both an input and a clobber.
36
+ var r0_out: usize = undefined;
29
37
  return asm volatile (
30
38
  \\ sc
31
39
  \\ bns+ 1f
32
40
  \\ neg 3, 3
33
41
  \\ 1:
34
42
  : [ret] "={r3}" (-> usize),
43
+ [r0_out] "={r0}" (r0_out),
35
44
  : [number] "{r0}" (@intFromEnum(number)),
36
45
  [arg1] "{r3}" (arg1),
37
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
46
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
38
47
  }
39
48
 
40
49
  pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
50
+ // These registers are both inputs and clobbers.
51
+ var r0_out: usize = undefined;
52
+ var r4_out: usize = undefined;
41
53
  return asm volatile (
42
54
  \\ sc
43
55
  \\ bns+ 1f
44
56
  \\ neg 3, 3
45
57
  \\ 1:
46
58
  : [ret] "={r3}" (-> usize),
59
+ [r0_out] "={r0}" (r0_out),
60
+ [r4_out] "={r4}" (r4_out),
47
61
  : [number] "{r0}" (@intFromEnum(number)),
48
62
  [arg1] "{r3}" (arg1),
49
63
  [arg2] "{r4}" (arg2),
50
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
64
+ : .{ .memory = true, .cr0 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
51
65
  }
52
66
 
53
67
  pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
68
+ // These registers are both inputs and clobbers.
69
+ var r0_out: usize = undefined;
70
+ var r4_out: usize = undefined;
71
+ var r5_out: usize = undefined;
54
72
  return asm volatile (
55
73
  \\ sc
56
74
  \\ bns+ 1f
57
75
  \\ neg 3, 3
58
76
  \\ 1:
59
77
  : [ret] "={r3}" (-> usize),
78
+ [r0_out] "={r0}" (r0_out),
79
+ [r4_out] "={r4}" (r4_out),
80
+ [r5_out] "={r5}" (r5_out),
60
81
  : [number] "{r0}" (@intFromEnum(number)),
61
82
  [arg1] "{r3}" (arg1),
62
83
  [arg2] "{r4}" (arg2),
63
84
  [arg3] "{r5}" (arg3),
64
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
85
+ : .{ .memory = true, .cr0 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
65
86
  }
66
87
 
67
88
  pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89
+ // These registers are both inputs and clobbers.
90
+ var r0_out: usize = undefined;
91
+ var r4_out: usize = undefined;
92
+ var r5_out: usize = undefined;
93
+ var r6_out: usize = undefined;
68
94
  return asm volatile (
69
95
  \\ sc
70
96
  \\ bns+ 1f
71
97
  \\ neg 3, 3
72
98
  \\ 1:
73
99
  : [ret] "={r3}" (-> usize),
100
+ [r0_out] "={r0}" (r0_out),
101
+ [r4_out] "={r4}" (r4_out),
102
+ [r5_out] "={r5}" (r5_out),
103
+ [r6_out] "={r6}" (r6_out),
74
104
  : [number] "{r0}" (@intFromEnum(number)),
75
105
  [arg1] "{r3}" (arg1),
76
106
  [arg2] "{r4}" (arg2),
77
107
  [arg3] "{r5}" (arg3),
78
108
  [arg4] "{r6}" (arg4),
79
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
109
+ : .{ .memory = true, .cr0 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
80
110
  }
81
111
 
82
112
  pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
113
+ // These registers are both inputs and clobbers.
114
+ var r0_out: usize = undefined;
115
+ var r4_out: usize = undefined;
116
+ var r5_out: usize = undefined;
117
+ var r6_out: usize = undefined;
118
+ var r7_out: usize = undefined;
83
119
  return asm volatile (
84
120
  \\ sc
85
121
  \\ bns+ 1f
86
122
  \\ neg 3, 3
87
123
  \\ 1:
88
124
  : [ret] "={r3}" (-> usize),
125
+ [r0_out] "={r0}" (r0_out),
126
+ [r4_out] "={r4}" (r4_out),
127
+ [r5_out] "={r5}" (r5_out),
128
+ [r6_out] "={r6}" (r6_out),
129
+ [r7_out] "={r7}" (r7_out),
89
130
  : [number] "{r0}" (@intFromEnum(number)),
90
131
  [arg1] "{r3}" (arg1),
91
132
  [arg2] "{r4}" (arg2),
92
133
  [arg3] "{r5}" (arg3),
93
134
  [arg4] "{r6}" (arg4),
94
135
  [arg5] "{r7}" (arg5),
95
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
136
+ : .{ .memory = true, .cr0 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
96
137
  }
97
138
 
98
139
  pub fn syscall6(
@@ -104,12 +145,25 @@ pub fn syscall6(
104
145
  arg5: usize,
105
146
  arg6: usize,
106
147
  ) usize {
148
+ // These registers are both inputs and clobbers.
149
+ var r0_out: usize = undefined;
150
+ var r4_out: usize = undefined;
151
+ var r5_out: usize = undefined;
152
+ var r6_out: usize = undefined;
153
+ var r7_out: usize = undefined;
154
+ var r8_out: usize = undefined;
107
155
  return asm volatile (
108
156
  \\ sc
109
157
  \\ bns+ 1f
110
158
  \\ neg 3, 3
111
159
  \\ 1:
112
160
  : [ret] "={r3}" (-> usize),
161
+ [r0_out] "={r0}" (r0_out),
162
+ [r4_out] "={r4}" (r4_out),
163
+ [r5_out] "={r5}" (r5_out),
164
+ [r6_out] "={r6}" (r6_out),
165
+ [r7_out] "={r7}" (r7_out),
166
+ [r8_out] "={r8}" (r8_out),
113
167
  : [number] "{r0}" (@intFromEnum(number)),
114
168
  [arg1] "{r3}" (arg1),
115
169
  [arg2] "{r4}" (arg2),
@@ -117,7 +171,7 @@ pub fn syscall6(
117
171
  [arg4] "{r6}" (arg4),
118
172
  [arg5] "{r7}" (arg5),
119
173
  [arg6] "{r8}" (arg6),
120
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
174
+ : .{ .memory = true, .cr0 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
121
175
  }
122
176
 
123
177
  pub fn clone() callconv(.naked) usize {
@@ -178,11 +232,19 @@ pub fn clone() callconv(.naked) usize {
178
232
  pub const restore = restore_rt;
179
233
 
180
234
  pub fn restore_rt() callconv(.naked) noreturn {
181
- asm volatile (
182
- \\ sc
183
- :
184
- : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
185
- : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
235
+ switch (@import("builtin").zig_backend) {
236
+ .stage2_c => asm volatile (
237
+ \\ li 0, %[number]
238
+ \\ sc
239
+ :
240
+ : [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
241
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
242
+ else => _ = asm volatile (
243
+ \\ sc
244
+ :
245
+ : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
246
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
247
+ }
186
248
  }
187
249
 
188
250
  pub const F = struct {
package/std/os/linux.zig CHANGED
@@ -1238,11 +1238,14 @@ pub fn access(path: [*:0]const u8, mode: u32) usize {
1238
1238
  if (@hasField(SYS, "access")) {
1239
1239
  return syscall2(.access, @intFromPtr(path), mode);
1240
1240
  } else {
1241
- return syscall4(.faccessat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(path), mode, 0);
1241
+ return faccessat(AT.FDCWD, path, mode, 0);
1242
1242
  }
1243
1243
  }
1244
1244
 
1245
1245
  pub fn faccessat(dirfd: i32, path: [*:0]const u8, mode: u32, flags: u32) usize {
1246
+ if (flags == 0) {
1247
+ return syscall3(.faccessat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), mode);
1248
+ }
1246
1249
  return syscall4(.faccessat2, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), mode, flags);
1247
1250
  }
1248
1251
 
@@ -9799,7 +9802,9 @@ pub const wrapped = struct {
9799
9802
  };
9800
9803
 
9801
9804
  pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, len: usize, flags: u32) CopyFileRangeError!usize {
9802
- const rc = system.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
9805
+ const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
9806
+ const sys = if (use_c) std.c else std.os.linux;
9807
+ const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
9803
9808
  switch (errno(rc)) {
9804
9809
  .SUCCESS => return @intCast(rc),
9805
9810
  .BADF => return error.BadFileFlags,
@@ -1,5 +1,5 @@
1
1
  const std = @import("std");
2
- const uefi = std.uefi;
2
+ const uefi = std.os.uefi;
3
3
  const Guid = uefi.Guid;
4
4
  const Handle = uefi.Handle;
5
5
  const Status = uefi.Status;
@@ -90,7 +90,7 @@ pub const MemoryType = enum(u32) {
90
90
  return @truncate(as_int - vendor_start);
91
91
  }
92
92
 
93
- pub fn format(self: MemoryType, w: *std.io.Writer) std.io.WriteError!void {
93
+ pub fn format(self: MemoryType, w: *std.io.Writer) std.io.Writer.Error!void {
94
94
  if (self.toOem()) |oemval|
95
95
  try w.print("OEM({X})", .{oemval})
96
96
  else if (self.toVendor()) |vendorval|
package/std/pie.zig CHANGED
@@ -177,7 +177,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
177
177
  \\ jg 2f
178
178
  \\ 1: .quad _DYNAMIC - .
179
179
  \\ 2:
180
- : [ret] "=r" (-> [*]const elf.Dyn),
180
+ : [ret] "=a" (-> [*]const elf.Dyn),
181
181
  ),
182
182
  // The compiler does not necessarily have any obligation to load the `l7` register (pointing
183
183
  // to the GOT), so do it ourselves just in case.
package/std/posix.zig CHANGED
@@ -6387,14 +6387,16 @@ pub const CopyFileRangeError = error{
6387
6387
  ///
6388
6388
  /// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.
6389
6389
  pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
6390
- if (builtin.os.tag == .freebsd or
6391
- (comptime builtin.os.tag == .linux and std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 })))
6392
- {
6390
+ if (builtin.os.tag == .freebsd or builtin.os.tag == .linux) {
6391
+ const use_c = native_os != .linux or
6392
+ std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
6393
+ const sys = if (use_c) std.c else linux;
6394
+
6393
6395
  var off_in_copy: i64 = @bitCast(off_in);
6394
6396
  var off_out_copy: i64 = @bitCast(off_out);
6395
6397
 
6396
6398
  while (true) {
6397
- const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
6399
+ const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
6398
6400
  if (native_os == .freebsd) {
6399
6401
  switch (errno(rc)) {
6400
6402
  .SUCCESS => return @intCast(rc),
@@ -52,6 +52,8 @@ term: ?(SpawnError!Term),
52
52
  argv: []const []const u8,
53
53
 
54
54
  /// Leave as null to use the current env map using the supplied allocator.
55
+ /// Required if unable to access the current env map (e.g. building a library on
56
+ /// some platforms).
55
57
  env_map: ?*const EnvMap,
56
58
 
57
59
  stdin_behavior: StdIo,
@@ -414,6 +416,8 @@ pub fn run(args: struct {
414
416
  argv: []const []const u8,
415
417
  cwd: ?[]const u8 = null,
416
418
  cwd_dir: ?fs.Dir = null,
419
+ /// Required if unable to access the current env map (e.g. building a
420
+ /// library on some platforms).
417
421
  env_map: ?*const EnvMap = null,
418
422
  max_output_bytes: usize = 50 * 1024,
419
423
  expand_arg0: Arg0Expand = .no_expand,
@@ -614,7 +618,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
614
618
  })).ptr;
615
619
  } else {
616
620
  // TODO come up with a solution for this.
617
- @compileError("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process");
621
+ @panic("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process");
618
622
  }
619
623
  };
620
624
 
package/std/process.zig CHANGED
@@ -1753,7 +1753,8 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
1753
1753
  if (std.os.linux.E.init(result) != .SUCCESS) {
1754
1754
  return error.UnknownTotalSystemMemory;
1755
1755
  }
1756
- return info.totalram * info.mem_unit;
1756
+ // Promote to u64 to avoid overflow on systems where info.totalram is a 32-bit usize
1757
+ return @as(u64, info.totalram) * info.mem_unit;
1757
1758
  },
1758
1759
  .freebsd => {
1759
1760
  var physmem: c_ulong = undefined;
@@ -1762,7 +1763,20 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
1762
1763
  error.NameTooLong, error.UnknownName => unreachable,
1763
1764
  else => return error.UnknownTotalSystemMemory,
1764
1765
  };
1765
- return @as(usize, @intCast(physmem));
1766
+ return @as(u64, @intCast(physmem));
1767
+ },
1768
+ // whole Darwin family
1769
+ .driverkit, .ios, .macos, .tvos, .visionos, .watchos => {
1770
+ // "hw.memsize" returns uint64_t
1771
+ var physmem: u64 = undefined;
1772
+ var len: usize = @sizeOf(u64);
1773
+ posix.sysctlbynameZ("hw.memsize", &physmem, &len, null, 0) catch |err| switch (err) {
1774
+ error.PermissionDenied => unreachable, // only when setting values,
1775
+ error.SystemResources => unreachable, // memory already on the stack
1776
+ error.UnknownName => unreachable, // constant, known good value
1777
+ else => return error.UnknownTotalSystemMemory,
1778
+ };
1779
+ return physmem;
1766
1780
  },
1767
1781
  .openbsd => {
1768
1782
  const mib: [2]c_int = [_]c_int{
package/std/sort/pdq.zig CHANGED
@@ -227,7 +227,7 @@ fn partialInsertionSort(a: usize, b: usize, context: anytype) bool {
227
227
  // shift the smaller element to the left.
228
228
  if (i - a >= 2) {
229
229
  var j = i - 1;
230
- while (j >= 1) : (j -= 1) {
230
+ while (j > a) : (j -= 1) {
231
231
  if (!context.lessThan(j, j - 1)) break;
232
232
  context.swap(j, j - 1);
233
233
  }
@@ -328,3 +328,50 @@ fn reverseRange(a: usize, b: usize, context: anytype) void {
328
328
  j -= 1;
329
329
  }
330
330
  }
331
+
332
+ test "pdqContext respects arbitrary range boundaries" {
333
+ // Regression test for issue #25250
334
+ // pdqsort should never access indices outside the specified [a, b) range
335
+ var data: [2000]i32 = @splat(0);
336
+
337
+ // Fill with data that triggers the partialInsertionSort path
338
+ for (0..data.len) |i| {
339
+ data[i] = @intCast(@mod(@as(i32, @intCast(i)) * 7, 100));
340
+ }
341
+
342
+ const TestContext = struct {
343
+ items: []i32,
344
+ range_start: usize,
345
+ range_end: usize,
346
+
347
+ pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
348
+ // Assert indices are within the expected range
349
+ testing.expect(a >= ctx.range_start and a < ctx.range_end) catch @panic("index a out of range");
350
+ testing.expect(b >= ctx.range_start and b < ctx.range_end) catch @panic("index b out of range");
351
+ return ctx.items[a] < ctx.items[b];
352
+ }
353
+
354
+ pub fn swap(ctx: @This(), a: usize, b: usize) void {
355
+ // Assert indices are within the expected range
356
+ testing.expect(a >= ctx.range_start and a < ctx.range_end) catch @panic("index a out of range");
357
+ testing.expect(b >= ctx.range_start and b < ctx.range_end) catch @panic("index b out of range");
358
+ mem.swap(i32, &ctx.items[a], &ctx.items[b]);
359
+ }
360
+ };
361
+
362
+ // Test sorting a sub-range that doesn't start at 0
363
+ const start = 1118;
364
+ const end = 1764;
365
+ const ctx = TestContext{
366
+ .items = &data,
367
+ .range_start = start,
368
+ .range_end = end,
369
+ };
370
+
371
+ pdqContext(start, end, ctx);
372
+
373
+ // Verify the range is sorted
374
+ for ((start + 1)..end) |i| {
375
+ try testing.expect(data[i - 1] <= data[i]);
376
+ }
377
+ }
package/std/testing.zig CHANGED
@@ -1249,3 +1249,63 @@ pub const Reader = struct {
1249
1249
  return n;
1250
1250
  }
1251
1251
  };
1252
+
1253
+ /// A `std.Io.Reader` that gets its data from another `std.Io.Reader`, and always
1254
+ /// writes to its own buffer (and returns 0) during `stream` and `readVec`.
1255
+ pub const ReaderIndirect = struct {
1256
+ in: *std.Io.Reader,
1257
+ interface: std.Io.Reader,
1258
+
1259
+ pub fn init(in: *std.Io.Reader, buffer: []u8) ReaderIndirect {
1260
+ return .{
1261
+ .in = in,
1262
+ .interface = .{
1263
+ .vtable = &.{
1264
+ .stream = stream,
1265
+ .readVec = readVec,
1266
+ },
1267
+ .buffer = buffer,
1268
+ .seek = 0,
1269
+ .end = 0,
1270
+ },
1271
+ };
1272
+ }
1273
+
1274
+ fn readVec(r: *std.Io.Reader, _: [][]u8) std.Io.Reader.Error!usize {
1275
+ try streamInner(r);
1276
+ return 0;
1277
+ }
1278
+
1279
+ fn stream(r: *std.Io.Reader, _: *std.Io.Writer, _: std.Io.Limit) std.Io.Reader.StreamError!usize {
1280
+ try streamInner(r);
1281
+ return 0;
1282
+ }
1283
+
1284
+ fn streamInner(r: *std.Io.Reader) std.Io.Reader.Error!void {
1285
+ const r_indirect: *ReaderIndirect = @alignCast(@fieldParentPtr("interface", r));
1286
+
1287
+ // If there's no room remaining in the buffer at all, make room.
1288
+ if (r.buffer.len == r.end) {
1289
+ try r.rebase(r.buffer.len);
1290
+ }
1291
+
1292
+ var writer: std.Io.Writer = .{
1293
+ .buffer = r.buffer,
1294
+ .end = r.end,
1295
+ .vtable = &.{
1296
+ .drain = std.Io.Writer.unreachableDrain,
1297
+ .rebase = std.Io.Writer.unreachableRebase,
1298
+ },
1299
+ };
1300
+ defer r.end = writer.end;
1301
+
1302
+ r_indirect.in.streamExact(&writer, r.buffer.len - r.end) catch |err| switch (err) {
1303
+ // Only forward EndOfStream if no new bytes were written to the buffer
1304
+ error.EndOfStream => |e| if (r.end == writer.end) {
1305
+ return e;
1306
+ },
1307
+ error.WriteFailed => unreachable,
1308
+ else => |e| return e,
1309
+ };
1310
+ }
1311
+ };
@@ -154,7 +154,11 @@ pub fn next(bc: *BitcodeReader) !?Item {
154
154
  Abbrev.Builtin.enter_subblock.toRecordId() => {
155
155
  const block_id: u32 = @intCast(record.operands[0]);
156
156
  switch (block_id) {
157
- Block.block_info => try bc.parseBlockInfoBlock(),
157
+ Block.block_info => {
158
+ try bc.startBlock(Block.block_info, @intCast(record.operands[1]));
159
+ try bc.parseBlockInfoBlock();
160
+ try bc.endBlock();
161
+ },
158
162
  Block.first_reserved...Block.last_standard => return error.UnsupportedBlockId,
159
163
  else => {
160
164
  try bc.startBlock(block_id, @intCast(record.operands[1]));
@@ -358,14 +358,11 @@ fn CpuinfoParser(comptime impl: anytype) type {
358
358
  return struct {
359
359
  fn parse(arch: Target.Cpu.Arch, reader: *std.Io.Reader) !?Target.Cpu {
360
360
  var obj: impl = .{};
361
- while (reader.takeDelimiterExclusive('\n')) |line| {
361
+ while (try reader.takeDelimiter('\n')) |line| {
362
362
  const colon_pos = mem.indexOfScalar(u8, line, ':') orelse continue;
363
363
  const key = mem.trimEnd(u8, line[0..colon_pos], " \t");
364
364
  const value = mem.trimStart(u8, line[colon_pos + 1 ..], " \t");
365
365
  if (!try obj.line_hook(key, value)) break;
366
- } else |err| switch (err) {
367
- error.EndOfStream => {},
368
- else => |e| return e,
369
366
  }
370
367
  return obj.finalize(arch);
371
368
  }
@@ -102,6 +102,7 @@ pub fn getExternalExecutor(
102
102
  else => "qemu-mips64el",
103
103
  },
104
104
  },
105
+ .or1k => Executor{ .qemu = "qemu-or1k" },
105
106
  .powerpc => Executor{ .qemu = "qemu-ppc" },
106
107
  .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
107
108
  .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
@@ -109,7 +110,7 @@ pub fn getExternalExecutor(
109
110
  .riscv64 => Executor{ .qemu = "qemu-riscv64" },
110
111
  .s390x => Executor{ .qemu = "qemu-s390x" },
111
112
  .sparc => Executor{
112
- .qemu = if (candidate.cpu.has(.sparc, .v9))
113
+ .qemu = if (candidate.cpu.has(.sparc, .v8plus))
113
114
  "qemu-sparc32plus"
114
115
  else
115
116
  "qemu-sparc",
@@ -121,7 +122,7 @@ pub fn getExternalExecutor(
121
122
  else => Executor{ .qemu = "qemu-x86_64" },
122
123
  },
123
124
  .xtensa => Executor{ .qemu = "qemu-xtensa" },
124
- else => return bad_result,
125
+ else => bad_result,
125
126
  };
126
127
  }
127
128
 
package/std/zon/parse.zig CHANGED
@@ -717,6 +717,7 @@ const Parser = struct {
717
717
 
718
718
  elem.* = try self.parseExpr(array_info.child, nodes.at(@intCast(i)));
719
719
  }
720
+ if (array_info.sentinel()) |s| result[result.len] = s;
720
721
  return result;
721
722
  }
722
723
 
package/ubsan_rt.zig CHANGED
@@ -627,7 +627,7 @@ fn exportHandler(
627
627
  // Work around x86_64 backend limitation.
628
628
  const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
629
629
  const N = "__ubsan_handle_" ++ sym_name;
630
- @export(handler, .{ .name = N, .linkage = linkage });
630
+ @export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
631
631
  }
632
632
 
633
633
  fn exportHandlerWithAbort(
@@ -639,11 +639,11 @@ fn exportHandlerWithAbort(
639
639
  const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
640
640
  {
641
641
  const N = "__ubsan_handle_" ++ sym_name;
642
- @export(handler, .{ .name = N, .linkage = linkage });
642
+ @export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
643
643
  }
644
644
  {
645
645
  const N = "__ubsan_handle_" ++ sym_name ++ "_abort";
646
- @export(abort_handler, .{ .name = N, .linkage = linkage });
646
+ @export(abort_handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
647
647
  }
648
648
  }
649
649