mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
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.
This commit is contained in:
parent
66630f6c93
commit
03ad862197
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user