authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-05 04:59:31-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-05 17:15:56-05:00
log0bf44c30934bced6fc8f6451cf418ae40db665e6
treec9d715c9907060ef77c1cd807c3ce42e1e133f15
parent137787edbb1320ce50bd4193d69f21ffaf8593e8

x86_64: fix `@errorName` data

The final offset was clobbering the first error name, which is revealed by an out of bounds when the global error set is empty. Closes #22362

4 files changed, 44 insertions(+), 9 deletions(-)

src/codegen.zig+13-9
...@@ -148,19 +148,23 @@ pub fn generateLazySymbol(...@@ -148,19 +148,23 @@ pub fn generateLazySymbol(
148 if (lazy_sym.ty == .anyerror_type) {148 if (lazy_sym.ty == .anyerror_type) {
149 alignment.* = .@"4";149 alignment.* = .@"4";
150 const err_names = ip.global_error_set.getNamesFromMainThread();150 const err_names = ip.global_error_set.getNamesFromMainThread();
151 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);151 var offset_index: u32 = @intCast(code.items.len);
152 var offset = code.items.len;152 var string_index: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
153 try code.resize((err_names.len + 1) * 4);153 try code.resize(offset_index + string_index);
154 mem.writeInt(u32, code.items[offset_index..][0..4], @intCast(err_names.len), endian);
155 if (err_names.len == 0) return .ok;
156 offset_index += 4;
154 for (err_names) |err_name_nts| {157 for (err_names) |err_name_nts| {
155 const err_name = err_name_nts.toSlice(ip);158 const err_name = err_name_nts.toSlice(ip);
156 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);159 mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
157 offset += 4;160 offset_index += 4;
158 try code.ensureUnusedCapacity(err_name.len + 1);161 try code.ensureUnusedCapacity(err_name.len + 1);
159 code.appendSliceAssumeCapacity(err_name);162 code.appendSliceAssumeCapacity(err_name);
160 code.appendAssumeCapacity(0);163 code.appendAssumeCapacity(0);
164 string_index += @intCast(err_name.len + 1);
161 }165 }
162 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);166 mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
163 return Result.ok;167 return .ok;
164 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") {168 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") {
165 alignment.* = .@"1";169 alignment.* = .@"1";
166 const enum_ty = Type.fromInterned(lazy_sym.ty);170 const enum_ty = Type.fromInterned(lazy_sym.ty);
...@@ -171,8 +175,8 @@ pub fn generateLazySymbol(...@@ -171,8 +175,8 @@ pub fn generateLazySymbol(
171 code.appendSliceAssumeCapacity(tag_name);175 code.appendSliceAssumeCapacity(tag_name);
172 code.appendAssumeCapacity(0);176 code.appendAssumeCapacity(0);
173 }177 }
174 return Result.ok;178 return .ok;
175 } else return .{ .fail = try ErrorMsg.create(179 } else return .{ .fail = try .create(
176 gpa,180 gpa,
177 src_loc,181 src_loc,
178 "TODO implement generateLazySymbol for {s} {}",182 "TODO implement generateLazySymbol for {s} {}",
test/standalone/build.zig.zon+3
...@@ -180,6 +180,9 @@...@@ -180,6 +180,9 @@
180 .run_output_caching = .{180 .run_output_caching = .{
181 .path = "run_output_caching",181 .path = "run_output_caching",
182 },182 },
183 .empty_global_error_set = .{
184 .path = "empty_global_error_set",
185 },
183 },186 },
184 .paths = .{187 .paths = .{
185 "build.zig",188 "build.zig",
test/standalone/empty_global_error_set/build.zig created+24
...@@ -0,0 +1,24 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4pub fn build(b: *std.Build) void {
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 for ([_]bool{ false, true }) |use_llvm| {
9 const main = b.addObject(.{
10 .name = "main",
11 .root_module = b.createModule(.{
12 .root_source_file = b.path("main.zig"),
13 .target = b.resolveTargetQuery(.{
14 .cpu_arch = .x86_64,
15 .os_tag = .linux,
16 }),
17 }),
18 .use_llvm = use_llvm,
19 .use_lld = use_llvm,
20 });
21 _ = main.getEmittedBin();
22 test_step.dependOn(&main.step);
23 }
24}
test/standalone/empty_global_error_set/main.zig created+4
...@@ -0,0 +1,4 @@
1fn errorName(err: anyerror) [:0]const u8 {
2 return @errorName(err);
3}
4export const error_name: *const anyopaque = &errorName;