Commit 8f8efcdd6e

xackus <14938807+xackus@users.noreply.github.com>
2021-05-09 22:59:22
translate-c: fix typedefs with multiple names
1 parent 9c03b39
Changed files (2)
src/translate_c.zig
@@ -447,7 +447,13 @@ fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void {
             // TODO https://github.com/ziglang/zig/issues/3756
             // TODO https://github.com/ziglang/zig/issues/1802
             const name = if (isZigPrimitiveType(decl_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ decl_name, c.getMangle() }) else decl_name;
-            try c.unnamed_typedefs.putNoClobber(c.gpa, addr, name);
+            const result = try c.unnamed_typedefs.getOrPut(c.gpa, addr);
+            if (result.found_existing) {
+                // One typedef can declare multiple names.
+                // Don't put this one in `decl_table` so it's processed later.
+                return;
+            }
+            result.entry.value = name;
             // Put this typedef in the decl_table to avoid redefinitions.
             try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), name);
         }
test/run_translated_c.zig
@@ -1476,4 +1476,18 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
         \\    return 0;
         \\}
     , "");
+
+    cases.add("typedef with multiple names",
+        \\#include <stdlib.h>
+        \\typedef struct {
+        \\    char field;
+        \\} a_t, b_t;
+        \\
+        \\int main(void) {
+        \\    a_t a = { .field = 42 };
+        \\    b_t b = a;
+        \\    if (b.field != 42) abort();
+        \\    return 0;
+        \\}
+    , "");
 }