diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2024-04-16 21:49:08 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2024-04-17 13:41:25 +0100 |
| commit | 03ad862197d27fb079d16cabdf2026da23aa2653 (patch) | |
| tree | 4a93dcada35e3bf50521efaa41679688cb16ab26 | |
| parent | 66630f6c93da0d219d74026742c1cb5f64e858e8 (diff) | |
| download | zig-03ad862197d27fb079d16cabdf2026da23aa2653.tar.gz zig-03ad862197d27fb079d16cabdf2026da23aa2653.zip | |
compiler: un-implement #19634
This commit reverts the handling of partially-undefined values in
bitcasting to transform these bits into an arbitrary numeric value,
like happens on `master` today.
As @andrewrk rightly points out, #19634 has unfortunate consequences
for the standard library, and likely requires more thought. To avoid
a major breaking change, it has been decided to revert this design
decision for now, and make a more informed decision further down the
line.
| -rw-r--r-- | lib/std/net.zig | 9 | ||||
| -rw-r--r-- | lib/std/packed_int_array.zig | 8 | ||||
| -rw-r--r-- | src/Sema/bitcast.zig | 26 | ||||
| -rw-r--r-- | test/cases/compile_errors/bitcast_undef.zig | 8 |
4 files changed, 21 insertions, 30 deletions
diff --git a/lib/std/net.zig b/lib/std/net.zig index ddbb414705..3126bfa93b 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -278,9 +278,6 @@ pub const Ip4Address = extern struct { }, }; const out_ptr = mem.asBytes(&result.sa.addr); - if (@inComptime()) { - @memset(out_ptr, 0); // TODO: #19634 - } var x: u8 = 0; var index: u8 = 0; @@ -392,9 +389,6 @@ pub const Ip6Address = extern struct { .addr = undefined, }, }; - if (@inComptime()) { - @memset(std.mem.asBytes(&result.sa.addr), 0); // TODO: #19634 - } var ip_slice: *[16]u8 = result.sa.addr[0..]; var tail: [16]u8 = undefined; @@ -513,9 +507,6 @@ pub const Ip6Address = extern struct { .addr = undefined, }, }; - if (@inComptime()) { - @memset(std.mem.asBytes(&result.sa.addr), 0); // TODO: #19634 - } var ip_slice: *[16]u8 = result.sa.addr[0..]; var tail: [16]u8 = undefined; diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig index d76df4d04e..02c721e7cf 100644 --- a/lib/std/packed_int_array.zig +++ b/lib/std/packed_int_array.zig @@ -214,10 +214,6 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptim /// or, more likely, an array literal. pub fn init(ints: [int_count]Int) Self { var self: Self = undefined; - if (@inComptime()) { - // TODO: #19634 - @memset(&self.bytes, 0xAA); - } for (ints, 0..) |int, i| self.set(i, int); return self; } @@ -225,10 +221,6 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptim /// Initialize all entries of a packed array to the same value. pub fn initAllTo(int: Int) Self { var self: Self = undefined; - if (@inComptime()) { - // TODO: #19634 - @memset(&self.bytes, 0xAA); - } self.setAll(int); return self; } diff --git a/src/Sema/bitcast.zig b/src/Sema/bitcast.zig index 7be51e87d8..8781009137 100644 --- a/src/Sema/bitcast.zig +++ b/src/Sema/bitcast.zig @@ -681,12 +681,24 @@ const PackValueBits = struct { const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu)); for (vals) |val| { - if (Value.fromInterned(val).isUndef(zcu)) { - // The value contains undef bits, so is considered entirely undef. - return zcu.undefValue(want_ty); - } + if (!Value.fromInterned(val).isUndef(zcu)) break; + } else { + // All bits of the value are `undefined`. + return zcu.undefValue(want_ty); } + // TODO: we need to decide how to handle partially-undef values here. + // Currently, a value with some undefined bits becomes `0xAA` so that we + // preserve the well-defined bits, because we can't currently represent + // a partially-undefined primitive (e.g. an int with some undef bits). + // In future, we probably want to take one of these two routes: + // * Define that if any bits are `undefined`, the entire value is `undefined`. + // This is a major breaking change, and probably a footgun. + // * Introduce tracking for partially-undef values at comptime. + // This would complicate a lot of operations in Sema, such as basic + // arithmetic. + // This design complexity is tracked by #19634. + ptr_cast: { if (vals.len != 1) break :ptr_cast; const val = Value.fromInterned(vals[0]); @@ -705,11 +717,15 @@ const PackValueBits = struct { } const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8)); + // We will skip writing undefined values, so mark the buffer as `0xAA` so we get "undefined" bits. + @memset(buf, 0xAA); var cur_bit_off: usize = 0; for (vals) |ip_val| { const val = Value.fromInterned(ip_val); const ty = val.typeOf(zcu); - try val.writeToPackedMemory(ty, zcu, buf, cur_bit_off); + if (!val.isUndef(zcu)) { + try val.writeToPackedMemory(ty, zcu, buf, cur_bit_off); + } cur_bit_off += @intCast(ty.bitSize(zcu)); } diff --git a/test/cases/compile_errors/bitcast_undef.zig b/test/cases/compile_errors/bitcast_undef.zig index 7b4a671672..fe9b40e463 100644 --- a/test/cases/compile_errors/bitcast_undef.zig +++ b/test/cases/compile_errors/bitcast_undef.zig @@ -4,17 +4,9 @@ export fn entry1() void { @compileLog(y); } -export fn entry2() void { - const x: packed struct { x: u16, y: u16 } = .{ .x = 123, .y = undefined }; - const y: u32 = @bitCast(x); - @compileLog(y); -} - // error // // :4:5: error: found compile log statement -// :10:5: note: also here // // Compile Log Output: // @as(u32, undefined) -// @as(u32, undefined) |
