Sema: correctly detect use of undefined within slices in @Type

Resolves: #14712
This commit is contained in:
mlugg 2023-03-10 00:42:56 +00:00 committed by Veikka Tuominen
parent b445bbfea2
commit 023753b469
3 changed files with 39 additions and 7 deletions

View File

@ -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,

View File

@ -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.

View File

@ -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