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 /src/Sema | |
| 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.
Diffstat (limited to 'src/Sema')
| -rw-r--r-- | src/Sema/bitcast.zig | 26 |
1 files changed, 21 insertions, 5 deletions
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)); } |
