mirror of
https://github.com/ziglang/zig.git
synced 2024-11-28 08:02:32 +00:00
Sema: implement comptime @memset
This commit is contained in:
parent
0f65cc9275
commit
83a7303bbf
37
src/Sema.zig
37
src/Sema.zig
@ -21959,17 +21959,44 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
||||
const dest_ptr_ty = sema.typeOf(dest_ptr);
|
||||
try checkSliceOrArrayType(sema, block, dest_src, dest_ptr_ty);
|
||||
|
||||
const elem_ty = dest_ptr_ty.elemType2();
|
||||
const elem = try sema.coerce(block, elem_ty, uncoerced_elem, value_src);
|
||||
const dest_elem_ty = dest_ptr_ty.elemType2();
|
||||
const target = sema.mod.getTarget();
|
||||
|
||||
const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
|
||||
if (!ptr_val.isComptimeMutablePtr()) break :rs dest_src;
|
||||
if (try sema.resolveMaybeUndefVal(elem)) |elem_val| {
|
||||
_ = elem_val;
|
||||
return sema.fail(block, src, "TODO: @memset at comptime", .{});
|
||||
if (try sema.resolveMaybeUndefVal(uncoerced_elem)) |_| {
|
||||
const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);
|
||||
const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
|
||||
break :rs dest_src;
|
||||
const len_u64 = (try len_val.getUnsignedIntAdvanced(target, sema)).?;
|
||||
const len = try sema.usizeCast(block, dest_src, len_u64);
|
||||
for (0..len) |i| {
|
||||
const elem_index = try sema.addIntUnsigned(Type.usize, i);
|
||||
const elem_ptr = try sema.elemPtr(
|
||||
block,
|
||||
src,
|
||||
dest_ptr,
|
||||
elem_index,
|
||||
src,
|
||||
true, // init
|
||||
false, // oob_safety
|
||||
);
|
||||
try sema.storePtr2(
|
||||
block,
|
||||
src,
|
||||
elem_ptr,
|
||||
dest_src,
|
||||
uncoerced_elem,
|
||||
value_src,
|
||||
.store,
|
||||
);
|
||||
}
|
||||
return;
|
||||
} else break :rs value_src;
|
||||
} else dest_src;
|
||||
|
||||
const elem = try sema.coerce(block, dest_elem_ty, uncoerced_elem, value_src);
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, runtime_src);
|
||||
_ = try block.addInst(.{
|
||||
.tag = if (block.wantSafety()) .memset_safe else .memset,
|
||||
|
@ -359,8 +359,7 @@ test "@memset on array pointers" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||
|
||||
try testMemsetArray();
|
||||
// TODO this doesn't pass yet
|
||||
// try comptime testMemsetArray();
|
||||
try comptime testMemsetArray();
|
||||
}
|
||||
|
||||
fn testMemsetArray() !void {
|
||||
@ -371,15 +370,7 @@ fn testMemsetArray() !void {
|
||||
try expect(foo[0] == 'A');
|
||||
try expect(foo[11] == 'A');
|
||||
try expect(foo[19] == 'A');
|
||||
|
||||
// memset array to undefined, ABI size == 1
|
||||
@setRuntimeSafety(true);
|
||||
@memset(&foo, undefined);
|
||||
try expect(foo[0] == 0xaa);
|
||||
try expect(foo[11] == 0xaa);
|
||||
try expect(foo[19] == 0xaa);
|
||||
}
|
||||
|
||||
{
|
||||
// memset array to non-undefined, ABI size > 1
|
||||
var foo: [20]u32 = undefined;
|
||||
@ -387,13 +378,6 @@ fn testMemsetArray() !void {
|
||||
try expect(foo[0] == 1234);
|
||||
try expect(foo[11] == 1234);
|
||||
try expect(foo[19] == 1234);
|
||||
|
||||
// memset array to undefined, ABI size > 1
|
||||
@setRuntimeSafety(true);
|
||||
@memset(&foo, undefined);
|
||||
try expect(foo[0] == 0xaaaaaaaa);
|
||||
try expect(foo[11] == 0xaaaaaaaa);
|
||||
try expect(foo[19] == 0xaaaaaaaa);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ pub export fn entry() void {
|
||||
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||
var slice: []u8 = &buf;
|
||||
const a: u32 = 1234;
|
||||
@memcpy(slice, @ptrCast([*]const u8, &a), 4);
|
||||
@memcpy(slice, @ptrCast([*]const u8, &a));
|
||||
}
|
||||
pub export fn entry1() void {
|
||||
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||
var ptr: *u8 = &buf[0];
|
||||
@memcpy(ptr, 0, 4);
|
||||
@memcpy(ptr, 0);
|
||||
}
|
||||
|
||||
// error
|
||||
|
@ -15,7 +15,7 @@ const E = enum(u32) {
|
||||
|
||||
pub fn main() !void {
|
||||
var e: E = undefined;
|
||||
@memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
@memset(@ptrCast([*]u8, &e)[0..@sizeOf(E)], 0x55);
|
||||
var n = @tagName(e);
|
||||
_ = n;
|
||||
return error.TestFailed;
|
||||
|
@ -15,7 +15,7 @@ const U = union(enum(u32)) {
|
||||
|
||||
pub fn main() !void {
|
||||
var u: U = undefined;
|
||||
@memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
|
||||
@memset(@ptrCast([*]u8, &u)[0..@sizeOf(U)], 0x55);
|
||||
var t: @typeInfo(U).Union.tag_type.? = u;
|
||||
var n = @tagName(t);
|
||||
_ = n;
|
||||
|
@ -15,7 +15,7 @@ const E = enum(u32) {
|
||||
|
||||
pub fn main() !void {
|
||||
var e: E = undefined;
|
||||
@memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
@memset(@ptrCast([*]u8, &e)[0..@sizeOf(E)], 0x55);
|
||||
switch (e) {
|
||||
.X, .Y => @breakpoint(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user