From c8d0e71de6c0e59b8f103526204b990fafe41f54 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 5 Oct 2022 01:21:11 -0400 Subject: [PATCH] c: fix mangling of error names Closes #12751 --- src/codegen/c.zig | 2 +- src/link/C.zig | 13 +++++++------ test/behavior/error.zig | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 704e8a1391..4bc573ba6c 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -746,7 +746,7 @@ pub const DeclGen = struct { .@"error" => { const payload = val.castTag(.@"error").?; // error values will be #defined at the top of the file - return writer.print("zig_error_{s}", .{payload.data.name}); + return writer.print("zig_error_{s}", .{fmtIdent(payload.data.name)}); }, else => { // In this case we are rendering an error union which has a diff --git a/src/link/C.zig b/src/link/C.zig index 955044f90d..ebe37a8192 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -275,13 +275,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) const err_typedef_index = f.all_buffers.items.len; f.all_buffers.items.len += 1; - render_errors: { - if (module.global_error_set.size == 0) break :render_errors; + if (module.global_error_set.size > 0) { + try err_typedef_writer.writeAll("enum {\n"); var it = module.global_error_set.iterator(); - while (it.next()) |entry| { - try err_typedef_writer.print("#define zig_error_{s} {d}\n", .{ entry.key_ptr.*, entry.value_ptr.* }); - } - try err_typedef_writer.writeByte('\n'); + while (it.next()) |entry| try err_typedef_writer.print(" zig_error_{s} = {d},\n", .{ + codegen.fmtIdent(entry.key_ptr.*), + entry.value_ptr.*, + }); + try err_typedef_writer.writeAll("};\n"); } // Typedefs, forward decls, and non-functions first. diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 6b64a0dc01..7fb125ab2a 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -843,3 +843,20 @@ fn non_errorable() void { test "catch within a function that calls no errorable functions" { non_errorable(); } + +test "error from comptime string" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + const name = "Weird error name!"; + const S = struct { + fn foo() !void { + return @field(anyerror, name); + } + }; + if (S.foo()) unreachable else |err| { + try expect(mem.eql(u8, name, @errorName(err))); + } +}