authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-21 01:35:35+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-21 11:30:20-07:00
log82c8e45a7e7659146b2ecda2929f01027b0658e4
treeade5d06f4eddc3270527423c836cbcc04959b3db
parent60fc18bd1c154f3c728a147c4574b5db8a17f08e

Sema: check @memset operand provides length

Resolves: #16698

2 files changed, 37 insertions(+), 1 deletions(-)

src/Sema.zig+20-1
...@@ -23938,7 +23938,26 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -23938,7 +23938,26 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
23938 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});23938 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
23939 }23939 }
2394023940
23941 const dest_elem_ty = dest_ptr_ty.elemType2(mod);23941 const dest_elem_ty: Type = dest_elem_ty: {
23942 const ptr_info = dest_ptr_ty.ptrInfo(mod);
23943 switch (ptr_info.flags.size) {
23944 .Slice => break :dest_elem_ty ptr_info.child.toType(),
23945 .One => {
23946 if (ptr_info.child.toType().zigTypeTag(mod) == .Array) {
23947 break :dest_elem_ty ptr_info.child.toType().childType(mod);
23948 }
23949 },
23950 .Many, .C => {},
23951 }
23952 return sema.failWithOwnedErrorMsg(msg: {
23953 const msg = try sema.errMsg(block, src, "unknown @memset length", .{});
23954 errdefer msg.destroy(sema.gpa);
23955 try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{
23956 dest_ptr_ty.fmt(mod),
23957 });
23958 break :msg msg;
23959 });
23960 };
2394223961
23943 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {23962 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
23944 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len"), dest_src);23963 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len"), dest_src);
test/cases/compile_errors/memset_no_length.zig created+17
...@@ -0,0 +1,17 @@
1export fn foo() void {
2 var ptr: [*]u8 = undefined;
3 @memset(ptr, 123);
4}
5export fn bar() void {
6 var ptr: [*c]bool = undefined;
7 @memset(ptr, true);
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :3:5: error: unknown @memset length
15// :3:13: note: destination type '[*]u8' provides no length
16// :7:5: error: unknown @memset length
17// :7:13: note: destination type '[*c]bool' provides no length