Sema: check @memset operand provides length

Resolves: #16698
This commit is contained in:
mlugg 2023-08-21 01:35:35 +01:00 committed by Andrew Kelley
parent 60fc18bd1c
commit 82c8e45a7e
2 changed files with 37 additions and 1 deletions

View File

@ -23938,7 +23938,26 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
}
const dest_elem_ty = dest_ptr_ty.elemType2(mod);
const dest_elem_ty: Type = dest_elem_ty: {
const ptr_info = dest_ptr_ty.ptrInfo(mod);
switch (ptr_info.flags.size) {
.Slice => break :dest_elem_ty ptr_info.child.toType(),
.One => {
if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
break :dest_elem_ty ptr_info.child.toType().childType(mod);
}
},
.Many, .C => {},
}
return sema.failWithOwnedErrorMsg(msg: {
const msg = try sema.errMsg(block, src, "unknown @memset length", .{});
errdefer msg.destroy(sema.gpa);
try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{
dest_ptr_ty.fmt(mod),
});
break :msg msg;
});
};
const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len"), dest_src);

View File

@ -0,0 +1,17 @@
export fn foo() void {
var ptr: [*]u8 = undefined;
@memset(ptr, 123);
}
export fn bar() void {
var ptr: [*c]bool = undefined;
@memset(ptr, true);
}
// error
// backend=stage2
// target=native
//
// :3:5: error: unknown @memset length
// :3:13: note: destination type '[*]u8' provides no length
// :7:5: error: unknown @memset length
// :7:13: note: destination type '[*c]bool' provides no length