Commit c8d0e71de6

Jacob Young <jacobly0@users.noreply.github.com>
2022-10-05 07:21:11
c: fix mangling of error names
Closes #12751
1 parent ab024d3
Changed files (3)
src
codegen
link
test
behavior
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
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.
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)));
+    }
+}