| ... | @@ -254,7 +254,7 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -254,7 +254,7 @@ pub fn zeroes(comptime T: type) T { |
| 254 | var structure: T = undefined; | 254 | var structure: T = undefined; |
| 255 | inline for (struct_info.fields) |field| { | 255 | inline for (struct_info.fields) |field| { |
| 256 | if (!field.is_comptime) { | 256 | if (!field.is_comptime) { |
| 257 | @field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name))); | 257 | @field(structure, field.name) = zeroes(field.type); |
| 258 | } | 258 | } |
| 259 | } | 259 | } |
| 260 | return structure; | 260 | return structure; |
| ... | @@ -292,12 +292,11 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -292,12 +292,11 @@ pub fn zeroes(comptime T: type) T { |
| 292 | return @splat(zeroes(info.child)); | 292 | return @splat(zeroes(info.child)); |
| 293 | }, | 293 | }, |
| 294 | .Union => |info| { | 294 | .Union => |info| { |
| 295 | if (comptime meta.containerLayout(T) == .Extern) { | 295 | if (info.layout == .Extern) { |
| 296 | // The C language specification states that (global) unions | 296 | var item: T = undefined; |
| 297 | // should be zero initialized to the first named member. | 297 | @memset(asBytes(&item), 0); |
| 298 | return @unionInit(T, info.fields[0].name, zeroes(info.fields[0].type)); | 298 | return item; |
| 299 | } | 299 | } |
| 300 | | | |
| 301 | @compileError("Can't set a " ++ @typeName(T) ++ " to zero."); | 300 | @compileError("Can't set a " ++ @typeName(T) ++ " to zero."); |
| 302 | }, | 301 | }, |
| 303 | .ErrorUnion, | 302 | .ErrorUnion, |
| ... | @@ -318,10 +317,14 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -318,10 +317,14 @@ pub fn zeroes(comptime T: type) T { |
| 318 | test "zeroes" { | 317 | test "zeroes" { |
| 319 | const C_struct = extern struct { | 318 | const C_struct = extern struct { |
| 320 | x: u32, | 319 | x: u32, |
| 321 | y: u32, | 320 | y: u32 align(128), |
| 322 | }; | 321 | }; |
| 323 | | 322 | |
| 324 | var a = zeroes(C_struct); | 323 | var a = zeroes(C_struct); |
| | 324 | |
| | 325 | // Extern structs should have padding zeroed out. |
| | 326 | try testing.expectEqualSlices(u8, &[_]u8{0} ** @sizeOf(@TypeOf(a)), asBytes(&a)); |
| | 327 | |
| 325 | a.y += 10; | 328 | a.y += 10; |
| 326 | | 329 | |
| 327 | try testing.expect(a.x == 0); | 330 | try testing.expect(a.x == 0); |
| ... | @@ -402,9 +405,11 @@ test "zeroes" { | ... | @@ -402,9 +405,11 @@ test "zeroes" { |
| 402 | | 405 | |
| 403 | var c = zeroes(C_union); | 406 | var c = zeroes(C_union); |
| 404 | try testing.expectEqual(@as(u8, 0), c.a); | 407 | try testing.expectEqual(@as(u8, 0), c.a); |
| | 408 | try testing.expectEqual(@as(u32, 0), c.b); |
| 405 | | 409 | |
| 406 | comptime var comptime_union = zeroes(C_union); | 410 | comptime var comptime_union = zeroes(C_union); |
| 407 | try testing.expectEqual(@as(u8, 0), comptime_union.a); | 411 | try testing.expectEqual(@as(u8, 0), comptime_union.a); |
| | 412 | try testing.expectEqual(@as(u32, 0), comptime_union.b); |
| 408 | | 413 | |
| 409 | // Ensure zero sized struct with fields is initialized correctly. | 414 | // Ensure zero sized struct with fields is initialized correctly. |
| 410 | _ = zeroes(struct { handle: void }); | 415 | _ = zeroes(struct { handle: void }); |