aboutsummaryrefslogtreecommitdiff
path: root/src/Sema
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-04-16 21:49:08 +0100
committermlugg <mlugg@mlugg.co.uk>2024-04-17 13:41:25 +0100
commit03ad862197d27fb079d16cabdf2026da23aa2653 (patch)
tree4a93dcada35e3bf50521efaa41679688cb16ab26 /src/Sema
parent66630f6c93da0d219d74026742c1cb5f64e858e8 (diff)
downloadzig-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.zig26
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));
}