mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
parent
8d036d1d78
commit
b8e6c42688
@ -2441,6 +2441,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
|
||||
.array_type_sentinel,
|
||||
.elem_type_index,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
.vector_elem_type,
|
||||
.vector_type,
|
||||
.indexable_ptr_len,
|
||||
@ -8302,9 +8303,12 @@ fn builtinCall(
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
},
|
||||
.memset => {
|
||||
const lhs = try expr(gz, scope, .{ .rl = .none }, params[0]);
|
||||
const lhs_ty = try gz.addUnNode(.typeof, lhs, params[0]);
|
||||
const elem_ty = try gz.addUnNode(.indexable_ptr_elem_type, lhs_ty, params[0]);
|
||||
_ = try gz.addPlNode(.memset, node, Zir.Inst.Bin{
|
||||
.lhs = try expr(gz, scope, .{ .rl = .none }, params[0]),
|
||||
.rhs = try expr(gz, scope, .{ .rl = .none }, params[1]),
|
||||
.lhs = lhs,
|
||||
.rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = elem_ty } }, params[1]),
|
||||
});
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
},
|
||||
|
||||
17
src/Sema.zig
17
src/Sema.zig
@ -1023,6 +1023,7 @@ fn analyzeBodyInner(
|
||||
.elem_val_node => try sema.zirElemValNode(block, inst),
|
||||
.elem_type_index => try sema.zirElemTypeIndex(block, inst),
|
||||
.elem_type => try sema.zirElemType(block, inst),
|
||||
.indexable_ptr_elem_type => try sema.zirIndexablePtrElemType(block, inst),
|
||||
.vector_elem_type => try sema.zirVectorElemType(block, inst),
|
||||
.enum_literal => try sema.zirEnumLiteral(block, inst),
|
||||
.int_from_enum => try sema.zirIntFromEnum(block, inst),
|
||||
@ -8106,6 +8107,22 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
return Air.internedToRef(ptr_ty.childType(mod).toIntern());
|
||||
}
|
||||
|
||||
fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const un_node = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = un_node.src();
|
||||
const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {
|
||||
error.GenericPoison => return .generic_poison_type,
|
||||
else => |e| return e,
|
||||
};
|
||||
try sema.checkMemOperand(block, src, ptr_ty);
|
||||
const elem_ty = switch (ptr_ty.ptrSize(mod)) {
|
||||
.Slice, .Many, .C => ptr_ty.childType(mod),
|
||||
.One => ptr_ty.childType(mod).childType(mod),
|
||||
};
|
||||
return Air.internedToRef(elem_ty.toIntern());
|
||||
}
|
||||
|
||||
fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const un_node = sema.code.instructions.items(.data)[inst].un_node;
|
||||
|
||||
@ -248,6 +248,10 @@ pub const Inst = struct {
|
||||
/// Given a pointer type, returns its element type.
|
||||
/// Uses the `un_node` field.
|
||||
elem_type,
|
||||
/// Given an indexable pointer (slice, many-ptr, single-ptr-to-array), returns its
|
||||
/// element type. Emits a compile error if the type is not an indexable pointer.
|
||||
/// Uses the `un_node` field.
|
||||
indexable_ptr_elem_type,
|
||||
/// Given a vector type, returns its element type.
|
||||
/// Uses the `un_node` field.
|
||||
vector_elem_type,
|
||||
@ -1021,6 +1025,7 @@ pub const Inst = struct {
|
||||
.vector_type,
|
||||
.elem_type_index,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
.vector_elem_type,
|
||||
.indexable_ptr_len,
|
||||
.anyframe_type,
|
||||
@ -1325,6 +1330,7 @@ pub const Inst = struct {
|
||||
.vector_type,
|
||||
.elem_type_index,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
.vector_elem_type,
|
||||
.indexable_ptr_len,
|
||||
.anyframe_type,
|
||||
@ -1557,6 +1563,7 @@ pub const Inst = struct {
|
||||
.vector_type = .pl_node,
|
||||
.elem_type_index = .bin,
|
||||
.elem_type = .un_node,
|
||||
.indexable_ptr_elem_type = .un_node,
|
||||
.vector_elem_type = .un_node,
|
||||
.indexable_ptr_len = .un_node,
|
||||
.anyframe_type = .un_node,
|
||||
|
||||
@ -154,6 +154,7 @@ const Writer = struct {
|
||||
.alloc_mut,
|
||||
.alloc_comptime_mut,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
.vector_elem_type,
|
||||
.indexable_ptr_len,
|
||||
.anyframe_type,
|
||||
|
||||
@ -135,3 +135,21 @@ test "memset with large array element, comptime known" {
|
||||
for (buf[3]) |elem| try expect(elem == 0);
|
||||
for (buf[4]) |elem| try expect(elem == 0);
|
||||
}
|
||||
|
||||
test "@memset provides result type" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct { x: u32 };
|
||||
|
||||
var buf1: [5]S = undefined;
|
||||
@memset(&buf1, .{ .x = @intCast(12) });
|
||||
|
||||
var buf2: [5]S = undefined;
|
||||
@memset(@as([]S, &buf2), .{ .x = @intCast(34) });
|
||||
|
||||
for (buf1) |s| try expect(s.x == 12);
|
||||
for (buf2) |s| try expect(s.x == 34);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user