mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Sema: correctly detect use of undefined within slices in @Type
Resolves: #14712
This commit is contained in:
parent
b445bbfea2
commit
023753b469
@ -18373,7 +18373,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
|
||||
const union_val = val.cast(Value.Payload.Union).?.data;
|
||||
const target = mod.getTarget();
|
||||
const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
|
||||
if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src);
|
||||
if (union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
|
||||
switch (@intToEnum(std.builtin.TypeId, tag_index)) {
|
||||
.Type => return Air.Inst.Ref.type_type,
|
||||
.Void => return Air.Inst.Ref.void_type,
|
||||
|
||||
@ -3144,13 +3144,32 @@ pub const Value = extern union {
|
||||
/// TODO: check for cases such as array that is not marked undef but all the element
|
||||
/// values are marked undef, or struct that is not marked undef but all fields are marked
|
||||
/// undef, etc.
|
||||
pub fn anyUndef(self: Value) bool {
|
||||
if (self.castTag(.aggregate)) |aggregate| {
|
||||
for (aggregate.data) |val| {
|
||||
if (val.anyUndef()) return true;
|
||||
}
|
||||
pub fn anyUndef(self: Value, mod: *Module) bool {
|
||||
switch (self.tag()) {
|
||||
.slice => {
|
||||
const payload = self.castTag(.slice).?;
|
||||
const len = payload.data.len.toUnsignedInt(mod.getTarget());
|
||||
|
||||
var elem_value_buf: ElemValueBuffer = undefined;
|
||||
var i: usize = 0;
|
||||
while (i < len) : (i += 1) {
|
||||
const elem_val = payload.data.ptr.elemValueBuffer(mod, i, &elem_value_buf);
|
||||
if (elem_val.anyUndef(mod)) return true;
|
||||
}
|
||||
},
|
||||
|
||||
.aggregate => {
|
||||
const payload = self.castTag(.aggregate).?;
|
||||
for (payload.data) |val| {
|
||||
if (val.anyUndef(mod)) return true;
|
||||
}
|
||||
},
|
||||
|
||||
.undef => return true,
|
||||
else => {},
|
||||
}
|
||||
return self.isUndef();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Asserts the value is not undefined and not unreachable.
|
||||
|
||||
@ -11,6 +11,18 @@ comptime {
|
||||
},
|
||||
});
|
||||
}
|
||||
comptime {
|
||||
const std = @import("std");
|
||||
const fields: [1]std.builtin.Type.StructField = undefined;
|
||||
_ = @Type(.{
|
||||
.Struct = .{
|
||||
.layout = .Auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
@ -18,3 +30,4 @@ comptime {
|
||||
//
|
||||
// :2:9: error: use of undefined value here causes undefined behavior
|
||||
// :5:9: error: use of undefined value here causes undefined behavior
|
||||
// :17:9: error: use of undefined value here causes undefined behavior
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user