From 82c8e45a7e7659146b2ecda2929f01027b0658e4 Mon Sep 17 00:00:00 2001 From: mlugg Date: Mon, 21 Aug 2023 01:35:35 +0100 Subject: [PATCH] Sema: check @memset operand provides length Resolves: #16698 --- src/Sema.zig | 21 ++++++++++++++++++- .../cases/compile_errors/memset_no_length.zig | 17 +++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/cases/compile_errors/memset_no_length.zig diff --git a/src/Sema.zig b/src/Sema.zig index c1f7eb2268..b4dd9fbd66 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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); diff --git a/test/cases/compile_errors/memset_no_length.zig b/test/cases/compile_errors/memset_no_length.zig new file mode 100644 index 0000000000..0355971cf9 --- /dev/null +++ b/test/cases/compile_errors/memset_no_length.zig @@ -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