Commit a8bd36c3d2

Evan Haas <evan@lagerdata.com>
2022-02-06 07:18:31
std: Allow `mem.zeroes` to work at comptime with extern union
Fixes #10797
1 parent 2e95bb0
Changed files (2)
lib/std/mem.zig
@@ -308,9 +308,7 @@ pub fn zeroes(comptime T: type) T {
             if (comptime meta.containerLayout(T) == .Extern) {
                 // The C language specification states that (global) unions
                 // should be zero initialized to the first named member.
-                var item: T = undefined;
-                @field(item, info.fields[0].name) = zeroes(@TypeOf(@field(item, info.fields[0].name)));
-                return item;
+                return @unionInit(T, info.fields[0].name, zeroes(info.fields[0].field_type));
             }
 
             @compileError("Can't set a " ++ @typeName(T) ++ " to zero.");
@@ -416,6 +414,9 @@ test "mem.zeroes" {
 
     var c = zeroes(C_union);
     try testing.expectEqual(@as(u8, 0), c.a);
+
+    comptime var comptime_union = zeroes(C_union);
+    try testing.expectEqual(@as(u8, 0), comptime_union.a);
 }
 
 /// Initializes all fields of the struct with their default value, or zero values if no default value is present.
test/run_translated_c.zig
@@ -1819,4 +1819,14 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
         \\    return 0;
         \\}
     , "");
+
+    cases.add("Zero-initialization of global union. Issue #10797",
+        \\#include <stdlib.h>
+        \\union U { int x; double y; };
+        \\union U u;
+        \\int main(void) {
+        \\    if (u.x != 0) abort();
+        \\    return 0;
+        \\}
+    , "");
 }