From e52cc47341d7936e40e46e221c7bb281421b4d57 Mon Sep 17 00:00:00 2001 From: IOKG04 Date: Fri, 19 Sep 2025 13:05:01 +0200 Subject: [PATCH 1/2] `orderSentinel` instead of `orderZ` --- lib/c/string.zig | 2 +- lib/std/mem.zig | 30 ++++++++++++++++++++++++++---- lib/std/zig/c_builtins.zig | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/c/string.zig b/lib/c/string.zig index a644093af57e..a24cb633b2f2 100644 --- a/lib/c/string.zig +++ b/lib/c/string.zig @@ -15,7 +15,7 @@ comptime { fn strcmp(s1: [*:0]const c_char, s2: [*:0]const c_char) callconv(.c) c_int { // We need to perform unsigned comparisons. - return switch (std.mem.orderZ(u8, @ptrCast(s1), @ptrCast(s2))) { + return switch (std.mem.orderSentinel(u8, 0, @ptrCast(s1), @ptrCast(s2))) { .lt => -1, .eq => 0, .gt => 1, diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 128ac695cff7..0036c3bda257 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -658,11 +658,21 @@ pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order { return math.order(lhs.len, rhs.len); } -/// Compares two many-item pointers with NUL-termination lexicographically. -pub fn orderZ(comptime T: type, lhs: [*:0]const T, rhs: [*:0]const T) math.Order { +/// Compares two many-item pointers with sentinel-termination lexicographically. +pub fn orderSentinel(comptime T: type, comptime s: T, lhs: [*:s]const T, rhs: [*:s]const T) math.Order { var i: usize = 0; - while (lhs[i] == rhs[i] and lhs[i] != 0) : (i += 1) {} - return math.order(lhs[i], rhs[i]); + while (lhs[i] == rhs[i] and lhs[i] != s) : (i += 1) {} + if (lhs[i] == s) { + return if (rhs[i] == s) .eq else .lt; + } else if (rhs[i] == s) { + return .gt; + } else { + return math.order(lhs[i], rhs[i]); + } +} +/// Deprecated in favor of `orderSentinel`. +pub fn orderZ(comptime T: type, lhs: [*:0]const T, rhs: [*:0]const T) math.Order { + return orderSentinel(T, 0, lhs, rhs); } test order { @@ -671,8 +681,20 @@ test order { try testing.expect(order(u8, "abc", "abc0") == .lt); try testing.expect(order(u8, "", "") == .eq); try testing.expect(order(u8, "", "a") == .lt); + try testing.expect(order(i8, &.{ -1, -2 }, &.{ -1, -2, -3 }) == .lt); } +test orderSentinel { + try testing.expect(orderSentinel(u8, 0, "abcd", "bee") == .lt); + try testing.expect(orderSentinel(u8, 0, "abc", "abc") == .eq); + try testing.expect(orderSentinel(u8, 0, "abc", "abc0") == .lt); + try testing.expect(orderSentinel(u8, 0, "", "") == .eq); + try testing.expect(orderSentinel(u8, 0, "", "a") == .lt); + try testing.expect(orderSentinel(i8, 0, &.{ -1, -2 }, &.{ -1, -2, -3 }) == .lt); + try testing.expect(orderSentinel(u4, 4, &.{ 1, 2, 3 }, &.{ 1, 2, 3 }) == .eq); + try testing.expect(orderSentinel(u4, 4, &.{ 1, 2, 3 }, &.{ 1, 2 }) == .gt); + try testing.expect(orderSentinel(u4, 4, &.{ 1, 2, 3 }, &.{ 1, 2, 3, 5 }) == .lt); +} test orderZ { try testing.expect(orderZ(u8, "abcd", "bee") == .lt); try testing.expect(orderZ(u8, "abc", "abc") == .eq); diff --git a/lib/std/zig/c_builtins.zig b/lib/std/zig/c_builtins.zig index 2f6c2e8aa5d7..71a80299dd8d 100644 --- a/lib/std/zig/c_builtins.zig +++ b/lib/std/zig/c_builtins.zig @@ -132,7 +132,7 @@ pub inline fn __builtin_strlen(s: [*c]const u8) usize { return std.mem.sliceTo(s, 0).len; } pub inline fn __builtin_strcmp(s1: [*c]const u8, s2: [*c]const u8) c_int { - return switch (std.mem.orderZ(u8, s1, s2)) { + return switch (std.mem.orderSentinel(u8, 0, s1, s2)) { .lt => -1, .eq => 0, .gt => 1, From 6d2e76b48b8285c079f73a27da272e036d0af04f Mon Sep 17 00:00:00 2001 From: IOKG04 Date: Fri, 19 Sep 2025 14:48:58 +0200 Subject: [PATCH 2/2] `dupeSentinel` instead of `dupeZ` closes https://github.com/ziglang/zig/issues/25285 --- lib/compiler/aro/aro/CodeGen.zig | 4 ++-- lib/std/Build/Watch/FsEvents.zig | 2 +- lib/std/debug.zig | 2 +- lib/std/fs/get_app_data_dir.zig | 2 +- lib/std/fs/test.zig | 4 ++-- lib/std/mem.zig | 2 +- lib/std/mem/Allocator.zig | 12 ++++++++---- lib/std/net.zig | 4 ++-- lib/std/os/plan9.zig | 2 +- lib/std/process.zig | 4 ++-- lib/std/process/Child.zig | 2 +- lib/std/zig/LibCInstallation.zig | 20 ++++++++++---------- lib/std/zig/tokenizer.zig | 2 +- src/Compilation.zig | 4 ++-- src/codegen/llvm.zig | 2 +- src/libs/mingw.zig | 2 +- src/link/Lld.zig | 4 ++-- src/main.zig | 10 +++++----- 18 files changed, 44 insertions(+), 40 deletions(-) diff --git a/lib/compiler/aro/aro/CodeGen.zig b/lib/compiler/aro/aro/CodeGen.zig index bfffb4117eea..505002921499 100644 --- a/lib/compiler/aro/aro/CodeGen.zig +++ b/lib/compiler/aro/aro/CodeGen.zig @@ -978,7 +978,7 @@ fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref { } } - const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice); + const duped_name = try c.builder.arena.allocator().dupeSentinel(u8, slice, 0); const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len); try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr }); return ref; @@ -1200,7 +1200,7 @@ fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Ty } } - const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice); + const duped_name = try c.builder.arena.allocator().dupeSentinel(u8, slice, 0); const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len); try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr }); break :blk ref; diff --git a/lib/std/Build/Watch/FsEvents.zig b/lib/std/Build/Watch/FsEvents.zig index c8c53813c2fb..d9c3e29f5fc0 100644 --- a/lib/std/Build/Watch/FsEvents.zig +++ b/lib/std/Build/Watch/FsEvents.zig @@ -193,7 +193,7 @@ pub fn setPaths(fse: *FsEvents, gpa: Allocator, steps: []const *std.Build.Step) } else { fse.watch_roots = try gpa.realloc(fse.watch_roots, need_dirs.count()); for (fse.watch_roots, need_dirs.keys()) |*out, in| { - out.* = try paths_arena.dupeZ(u8, in); + out.* = try paths_arena.dupeSentinel(u8, in, 0); } } if (enable_debug_logs) { diff --git a/lib/std/debug.zig b/lib/std/debug.zig index bd849a32d320..d2ecf95b21b5 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -661,7 +661,7 @@ pub fn defaultPanic( if (uefi.system_table.boot_services) |bs| { // ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220) - const exit_data = uefi.raw_pool_allocator.dupeZ(u16, exit_msg) catch @trap(); + const exit_data = uefi.raw_pool_allocator.dupeSentinel(u16, exit_msg, 0) catch @trap(); bs.exit(uefi.handle, .aborted, exit_data) catch {}; } @trap(); diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig index a256758a07e2..5b0c0d79271c 100644 --- a/lib/std/fs/get_app_data_dir.zig +++ b/lib/std/fs/get_app_data_dir.zig @@ -46,7 +46,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi .haiku => { var dir_path_buf: [std.fs.max_path_bytes]u8 = undefined; const rc = std.c.find_directory(.B_USER_SETTINGS_DIRECTORY, -1, true, &dir_path_buf, dir_path_buf.len); - const settings_dir = try allocator.dupeZ(u8, mem.sliceTo(&dir_path_buf, 0)); + const settings_dir = try allocator.dupeSentinel(u8, mem.sliceTo(&dir_path_buf, 0), 0); defer allocator.free(settings_dir); switch (rc) { 0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }), diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 65e86e4c2e40..c97a4781f600 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -105,7 +105,7 @@ const TestContext = struct { const allocator = self.arena.allocator(); const transformed_path = try self.transform_fn(allocator, self.dir, relative_path); if (native_os == .windows) { - const transformed_sep_path = try allocator.dupeZ(u8, transformed_path); + const transformed_sep_path = try allocator.dupeSentinel(u8, transformed_path, 0); std.mem.replaceScalar(u8, transformed_sep_path, switch (self.path_sep) { '/' => '\\', '\\' => '/', @@ -123,7 +123,7 @@ const TestContext = struct { pub fn toCanonicalPathSep(self: *TestContext, path: [:0]const u8) ![:0]const u8 { if (native_os == .windows) { const allocator = self.arena.allocator(); - const transformed_sep_path = try allocator.dupeZ(u8, path); + const transformed_sep_path = try allocator.dupeSentinel(u8, path, 0); std.mem.replaceScalar(u8, transformed_sep_path, '/', '\\'); return transformed_sep_path; } diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 0036c3bda257..ac46b5774fb1 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -4711,7 +4711,7 @@ test isAligned { } test "freeing empty string with null-terminated sentinel" { - const empty_string = try testing.allocator.dupeZ(u8, ""); + const empty_string = try testing.allocator.dupeSentinel(u8, "", 0); testing.allocator.free(empty_string); } diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index 1d1653d3a0c9..461a90490e7d 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -451,12 +451,16 @@ pub fn dupe(allocator: Allocator, comptime T: type, m: []const T) Error![]T { return new_buf; } -/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory. -pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) Error![:0]T { +/// Copies `m` to newly allocated memory, with a sentinel-terminated element. Caller owns the memory. +pub fn dupeSentinel(allocator: Allocator, comptime T: type, m: []const T, comptime s: T) Error![:s]T { const new_buf = try allocator.alloc(T, m.len + 1); @memcpy(new_buf[0..m.len], m); - new_buf[m.len] = 0; - return new_buf[0..m.len :0]; + new_buf[m.len] = s; + return new_buf[0..m.len :s]; +} +/// Deprecated in favor of `dupeSentinel` +pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) Error![:0]T { + return try dupeSentinel(allocator, T, m, 0); } /// An allocator that always fails to allocate. diff --git a/lib/std/net.zig b/lib/std/net.zig index 37fe2734d52d..794c81516869 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -910,7 +910,7 @@ pub fn getAddressList(gpa: Allocator, name: []const u8, port: u16) GetAddressLis errdefer result.deinit(); if (native_os == .windows) { - const name_c = try gpa.dupeZ(u8, name); + const name_c = try gpa.dupeSentinel(u8, name, 0); defer gpa.free(name_c); const port_c = try std.fmt.allocPrintSentinel(gpa, "{d}", .{port}, 0); @@ -982,7 +982,7 @@ pub fn getAddressList(gpa: Allocator, name: []const u8, port: u16) GetAddressLis } if (builtin.link_libc) { - const name_c = try gpa.dupeZ(u8, name); + const name_c = try gpa.dupeSentinel(u8, name, 0); defer gpa.free(name_c); const port_c = try std.fmt.allocPrintSentinel(gpa, "{d}", .{port}, 0); diff --git a/lib/std/os/plan9.zig b/lib/std/os/plan9.zig index b910e26c7134..4464095db3d0 100644 --- a/lib/std/os/plan9.zig +++ b/lib/std/os/plan9.zig @@ -297,7 +297,7 @@ pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, _: mode_t) usize { const dir_path = std.mem.span(@as([*:0]u8, @ptrCast(&dir_path_buf))); const total_path = std.fs.path.join(alloc, &.{ dir_path, std.mem.span(path) }) catch unreachable; // the allocation shouldn't fail because it should not exceed max_path_bytes fba.reset(); - const total_path_z = alloc.dupeZ(u8, total_path) catch unreachable; // should not exceed max_path_bytes + 1 + const total_path_z = alloc.dupeSentinel(u8, total_path, 0) catch unreachable; // should not exceed max_path_bytes + 1 return open(total_path_z.ptr, flags); } diff --git a/lib/std/process.zig b/lib/std/process.zig index 10025a5ea5b8..4260a4140c00 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1721,7 +1721,7 @@ pub fn execve( const arena = arena_allocator.allocator(); const argv_buf = try arena.allocSentinel(?[*:0]const u8, argv.len, null); - for (argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr; + for (argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr; const envp = m: { if (env_map) |m| { @@ -1999,7 +1999,7 @@ pub fn createEnvironFromExisting( }, .nothing => {}, }; - envp_buf[i] = try arena.dupeZ(u8, mem.span(line)); + envp_buf[i] = try arena.dupeSentinel(u8, mem.span(line), 0); i += 1; } diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index bbc08ac0c9f7..6b69e84a714c 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -591,7 +591,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { // Therefore, we do all the allocation for the execve() before the fork(). // This means we must do the null-termination of argv and env vars here. const argv_buf = try arena.allocSentinel(?[*:0]const u8, self.argv.len, null); - for (self.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr; + for (self.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr; const prog_fileno = 3; comptime assert(@max(posix.STDIN_FILENO, posix.STDOUT_FILENO, posix.STDERR_FILENO) + 1 == prog_fileno); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index 0414d32ee7d6..782947ff4e1b 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -58,7 +58,7 @@ pub fn parse( if (value.len == 0) { @field(self, field.name) = null; } else { - found_keys[i].allocated = try allocator.dupeZ(u8, value); + found_keys[i].allocated = try allocator.dupeSentinel(u8, value, 0); @field(self, field.name) = found_keys[i].allocated; } break; @@ -197,16 +197,16 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { } else if (is_haiku) { try self.findNativeIncludeDirPosix(args); try self.findNativeGccDirHaiku(args); - self.crt_dir = try args.allocator.dupeZ(u8, "/system/develop/lib"); + self.crt_dir = try args.allocator.dupeSentinel(u8, "/system/develop/lib", 0); } else if (builtin.target.os.tag.isSolarish()) { // There is only one libc, and its headers/libraries are always in the same spot. - self.include_dir = try args.allocator.dupeZ(u8, "/usr/include"); - self.sys_include_dir = try args.allocator.dupeZ(u8, "/usr/include"); - self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib/64"); + self.include_dir = try args.allocator.dupeSentinel(u8, "/usr/include", 0); + self.sys_include_dir = try args.allocator.dupeSentinel(u8, "/usr/include", 0); + self.crt_dir = try args.allocator.dupeSentinel(u8, "/usr/lib/64", 0); } else if (std.process.can_spawn) { try self.findNativeIncludeDirPosix(args); switch (builtin.target.os.tag) { - .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib"), + .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try args.allocator.dupeSentinel(u8, "/usr/lib", 0), .linux => try self.findNativeCrtDirPosix(args), else => {}, } @@ -330,7 +330,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F if (self.include_dir == null) { if (search_dir.accessZ(include_dir_example_file, .{})) |_| { - self.include_dir = try allocator.dupeZ(u8, search_path); + self.include_dir = try allocator.dupeSentinel(u8, search_path, 0); } else |err| switch (err) { error.FileNotFound => {}, else => return error.FileSystem, @@ -339,7 +339,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F if (self.sys_include_dir == null) { if (search_dir.accessZ(sys_include_dir_example_file, .{})) |_| { - self.sys_include_dir = try allocator.dupeZ(u8, search_path); + self.sys_include_dir = try allocator.dupeSentinel(u8, search_path, 0); } else |err| switch (err) { error.FileNotFound => {}, else => return error.FileSystem, @@ -622,10 +622,10 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { // So we detect failure by checking if the output matches exactly the input. if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound; switch (args.want_dirname) { - .full_path => return allocator.dupeZ(u8, line), + .full_path => return allocator.dupeSentinel(u8, line, 0), .only_dir => { const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound; - return allocator.dupeZ(u8, dirname); + return allocator.dupeSentinel(u8, dirname, 0); }, } } diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index de04ba41fecd..605c326c172c 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -1723,7 +1723,7 @@ fn testTokenize(source: [:0]const u8, expected_token_tags: []const Token.Tag) !v fn testPropertiesUpheld(context: void, source: []const u8) anyerror!void { _ = context; - const source0 = try std.testing.allocator.dupeZ(u8, source); + const source0 = try std.testing.allocator.dupeSentinel(u8, source, 0); defer std.testing.allocator.free(source0); var tokenizer = Tokenizer.init(source0); var tokenization_failed = false; diff --git a/src/Compilation.zig b/src/Compilation.zig index 34953ed11a12..fead05b1918a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1933,7 +1933,7 @@ pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options const comp: *Compilation = comp: { // We put the `Compilation` itself in the arena. Freeing the arena will free the module. // It's initialized later after we prepare the initialization options. - const root_name = try arena.dupeZ(u8, options.root_name); + const root_name = try arena.dupeSentinel(u8, options.root_name, 0); // The "any" values provided by resolved config only account for // explicitly-provided settings. We now make them additionally account @@ -5706,7 +5706,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module new_argv_with_sentinel[argv.items.len] = null; const new_argv = new_argv_with_sentinel[0..argv.items.len :null]; for (argv.items, 0..) |arg, i| { - new_argv[i] = try arena.dupeZ(u8, arg); + new_argv[i] = try arena.dupeSentinel(u8, arg, 0); } const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index ebdcdb6bcbf9..2781ac14ce52 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -936,7 +936,7 @@ pub const Object = struct { } const target_triple_sentinel = - try o.gpa.dupeZ(u8, o.builder.target_triple.slice(&o.builder).?); + try o.gpa.dupeSentinel(u8, o.builder.target_triple.slice(&o.builder).?, 0); defer o.gpa.free(target_triple_sentinel); const emit_asm_msg = options.asm_path orelse "(none)"; diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 5106815eff93..687428722131 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -345,7 +345,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; const llvm_bindings = @import("../codegen/llvm/bindings.zig"); - const def_final_path_z = try arena.dupeZ(u8, def_final_path); + const def_final_path_z = try arena.dupeSentinel(u8, def_final_path, 0); const lib_final_path_z = try comp.dirs.global_cache.joinZ(arena, &.{lib_final_path}); if (llvm_bindings.WriteImportLibrary( def_final_path_z.ptr, diff --git a/src/link/Lld.zig b/src/link/Lld.zig index c1845b9a727f..a28487152e08 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -286,7 +286,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { const comp = base.comp; const directory = base.emit.root_dir; // Just an alias to make it shorter to type. const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path}); - const full_out_path_z = try arena.dupeZ(u8, full_out_path); + const full_out_path_z = try arena.dupeSentinel(u8, full_out_path, 0); const opt_zcu = comp.zcu; const zcu_obj_path: ?Cache.Path = if (opt_zcu != null) p: { @@ -325,7 +325,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena)); } for (comp.win32_resource_table.keys()) |key| { - object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path)); + object_files.appendAssumeCapacity(try arena.dupeSentinel(u8, key.status.success.res_path, 0)); } if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena)); if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena)); diff --git a/src/main.zig b/src/main.zig index eef7b75fd0e7..b2153a8dc706 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4495,7 +4495,7 @@ fn runOrTestHotSwap( const arena = arena_allocator.allocator(); const argv_buf = try arena.allocSentinel(?[*:0]u8, argv.items.len, null); - for (argv.items, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr; + for (argv.items, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr; const pid = try PosixSpawn.spawn(argv.items[0], null, attr, argv_buf, std.c.environ); return pid; @@ -4623,10 +4623,10 @@ fn cmdTranslateC( new_argv_with_sentinel[clang_args_len] = null; const new_argv = new_argv_with_sentinel[0..clang_args_len :null]; for (argv.items, 0..) |arg, i| { - new_argv[i] = try arena.dupeZ(u8, arg); + new_argv[i] = try arena.dupeSentinel(u8, arg, 0); } for (c_source_file.extra_flags, 0..) |arg, i| { - new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); + new_argv[argv.items.len + i] = try arena.dupeSentinel(u8, arg, 0); } const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); @@ -5741,7 +5741,7 @@ extern "c" fn ZigLlvmAr_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int; fn argsCopyZ(alloc: Allocator, args: []const []const u8) ![:null]?[*:0]u8 { var argv = try alloc.allocSentinel(?[*:0]u8, args.len, null); for (args, 0..) |arg, i| { - argv[i] = try alloc.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation. + argv[i] = try alloc.dupeSentinel(u8, arg, 0); // TODO If there was an argsAllocZ we could avoid this allocation. } return argv; } @@ -6463,7 +6463,7 @@ fn cmdDumpLlvmInts( if (!build_options.have_llvm) fatal("compiler does not use LLVM; cannot dump LLVM integer sizes", .{}); - const triple = try arena.dupeZ(u8, args[0]); + const triple = try arena.dupeSentinel(u8, args[0], 0); const llvm = @import("codegen/llvm/bindings.zig");