| author | |
| committer | |
| log | b8e6c426887e92cc5a841a7dd58eb10ebfbe0d77 |
| tree | bda2f894bffbc95f62920f94121bf0f4e33cfae5 |
| parent | 8d036d1d78bd6db5fd39b30c6182196c1e49a3db |
Resolves: #169865 files changed, 49 insertions(+), 2 deletions(-)
src/AstGen.zig+6-2| ... | @@ -2441,6 +2441,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2441,6 +2441,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2441 | .array_type_sentinel, | 2441 | .array_type_sentinel, |
| 2442 | .elem_type_index, | 2442 | .elem_type_index, |
| 2443 | .elem_type, | 2443 | .elem_type, |
| 2444 | .indexable_ptr_elem_type, | ||
| 2444 | .vector_elem_type, | 2445 | .vector_elem_type, |
| 2445 | .vector_type, | 2446 | .vector_type, |
| 2446 | .indexable_ptr_len, | 2447 | .indexable_ptr_len, |
| ... | @@ -8302,9 +8303,12 @@ fn builtinCall( | ... | @@ -8302,9 +8303,12 @@ fn builtinCall( |
| 8302 | return rvalue(gz, ri, .void_value, node); | 8303 | return rvalue(gz, ri, .void_value, node); |
| 8303 | }, | 8304 | }, |
| 8304 | .memset => { | 8305 | .memset => { |
| 8306 | const lhs = try expr(gz, scope, .{ .rl = .none }, params[0]); | ||
| 8307 | const lhs_ty = try gz.addUnNode(.typeof, lhs, params[0]); | ||
| 8308 | const elem_ty = try gz.addUnNode(.indexable_ptr_elem_type, lhs_ty, params[0]); | ||
| 8305 | _ = try gz.addPlNode(.memset, node, Zir.Inst.Bin{ | 8309 | _ = try gz.addPlNode(.memset, node, Zir.Inst.Bin{ |
| 8306 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), | 8310 | .lhs = lhs, |
| 8307 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), | 8311 | .rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = elem_ty } }, params[1]), |
| 8308 | }); | 8312 | }); |
| 8309 | return rvalue(gz, ri, .void_value, node); | 8313 | return rvalue(gz, ri, .void_value, node); |
| 8310 | }, | 8314 | }, |
src/Sema.zig+17| ... | @@ -1023,6 +1023,7 @@ fn analyzeBodyInner( | ... | @@ -1023,6 +1023,7 @@ fn analyzeBodyInner( |
| 1023 | .elem_val_node => try sema.zirElemValNode(block, inst), | 1023 | .elem_val_node => try sema.zirElemValNode(block, inst), |
| 1024 | .elem_type_index => try sema.zirElemTypeIndex(block, inst), | 1024 | .elem_type_index => try sema.zirElemTypeIndex(block, inst), |
| 1025 | .elem_type => try sema.zirElemType(block, inst), | 1025 | .elem_type => try sema.zirElemType(block, inst), |
| 1026 | .indexable_ptr_elem_type => try sema.zirIndexablePtrElemType(block, inst), | ||
| 1026 | .vector_elem_type => try sema.zirVectorElemType(block, inst), | 1027 | .vector_elem_type => try sema.zirVectorElemType(block, inst), |
| 1027 | .enum_literal => try sema.zirEnumLiteral(block, inst), | 1028 | .enum_literal => try sema.zirEnumLiteral(block, inst), |
| 1028 | .int_from_enum => try sema.zirIntFromEnum(block, inst), | 1029 | .int_from_enum => try sema.zirIntFromEnum(block, inst), |
| ... | @@ -8106,6 +8107,22 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -8106,6 +8107,22 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8106 | return Air.internedToRef(ptr_ty.childType(mod).toIntern()); | 8107 | return Air.internedToRef(ptr_ty.childType(mod).toIntern()); |
| 8107 | } | 8108 | } |
| 8108 | 8109 | ||
| 8110 | fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | ||
| 8111 | const mod = sema.mod; | ||
| 8112 | const un_node = sema.code.instructions.items(.data)[inst].un_node; | ||
| 8113 | const src = un_node.src(); | ||
| 8114 | const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) { | ||
| 8115 | error.GenericPoison => return .generic_poison_type, | ||
| 8116 | else => |e| return e, | ||
| 8117 | }; | ||
| 8118 | try sema.checkMemOperand(block, src, ptr_ty); | ||
| 8119 | const elem_ty = switch (ptr_ty.ptrSize(mod)) { | ||
| 8120 | .Slice, .Many, .C => ptr_ty.childType(mod), | ||
| 8121 | .One => ptr_ty.childType(mod).childType(mod), | ||
| 8122 | }; | ||
| 8123 | return Air.internedToRef(elem_ty.toIntern()); | ||
| 8124 | } | ||
| 8125 | |||
| 8109 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8126 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8110 | const mod = sema.mod; | 8127 | const mod = sema.mod; |
| 8111 | const un_node = sema.code.instructions.items(.data)[inst].un_node; | 8128 | const un_node = sema.code.instructions.items(.data)[inst].un_node; |
src/Zir.zig+7| ... | @@ -248,6 +248,10 @@ pub const Inst = struct { | ... | @@ -248,6 +248,10 @@ pub const Inst = struct { |
| 248 | /// Given a pointer type, returns its element type. | 248 | /// Given a pointer type, returns its element type. |
| 249 | /// Uses the `un_node` field. | 249 | /// Uses the `un_node` field. |
| 250 | elem_type, | 250 | elem_type, |
| 251 | /// Given an indexable pointer (slice, many-ptr, single-ptr-to-array), returns its | ||
| 252 | /// element type. Emits a compile error if the type is not an indexable pointer. | ||
| 253 | /// Uses the `un_node` field. | ||
| 254 | indexable_ptr_elem_type, | ||
| 251 | /// Given a vector type, returns its element type. | 255 | /// Given a vector type, returns its element type. |
| 252 | /// Uses the `un_node` field. | 256 | /// Uses the `un_node` field. |
| 253 | vector_elem_type, | 257 | vector_elem_type, |
| ... | @@ -1021,6 +1025,7 @@ pub const Inst = struct { | ... | @@ -1021,6 +1025,7 @@ pub const Inst = struct { |
| 1021 | .vector_type, | 1025 | .vector_type, |
| 1022 | .elem_type_index, | 1026 | .elem_type_index, |
| 1023 | .elem_type, | 1027 | .elem_type, |
| 1028 | .indexable_ptr_elem_type, | ||
| 1024 | .vector_elem_type, | 1029 | .vector_elem_type, |
| 1025 | .indexable_ptr_len, | 1030 | .indexable_ptr_len, |
| 1026 | .anyframe_type, | 1031 | .anyframe_type, |
| ... | @@ -1325,6 +1330,7 @@ pub const Inst = struct { | ... | @@ -1325,6 +1330,7 @@ pub const Inst = struct { |
| 1325 | .vector_type, | 1330 | .vector_type, |
| 1326 | .elem_type_index, | 1331 | .elem_type_index, |
| 1327 | .elem_type, | 1332 | .elem_type, |
| 1333 | .indexable_ptr_elem_type, | ||
| 1328 | .vector_elem_type, | 1334 | .vector_elem_type, |
| 1329 | .indexable_ptr_len, | 1335 | .indexable_ptr_len, |
| 1330 | .anyframe_type, | 1336 | .anyframe_type, |
| ... | @@ -1557,6 +1563,7 @@ pub const Inst = struct { | ... | @@ -1557,6 +1563,7 @@ pub const Inst = struct { |
| 1557 | .vector_type = .pl_node, | 1563 | .vector_type = .pl_node, |
| 1558 | .elem_type_index = .bin, | 1564 | .elem_type_index = .bin, |
| 1559 | .elem_type = .un_node, | 1565 | .elem_type = .un_node, |
| 1566 | .indexable_ptr_elem_type = .un_node, | ||
| 1560 | .vector_elem_type = .un_node, | 1567 | .vector_elem_type = .un_node, |
| 1561 | .indexable_ptr_len = .un_node, | 1568 | .indexable_ptr_len = .un_node, |
| 1562 | .anyframe_type = .un_node, | 1569 | .anyframe_type = .un_node, |
src/print_zir.zig+1| ... | @@ -154,6 +154,7 @@ const Writer = struct { | ... | @@ -154,6 +154,7 @@ const Writer = struct { |
| 154 | .alloc_mut, | 154 | .alloc_mut, |
| 155 | .alloc_comptime_mut, | 155 | .alloc_comptime_mut, |
| 156 | .elem_type, | 156 | .elem_type, |
| 157 | .indexable_ptr_elem_type, | ||
| 157 | .vector_elem_type, | 158 | .vector_elem_type, |
| 158 | .indexable_ptr_len, | 159 | .indexable_ptr_len, |
| 159 | .anyframe_type, | 160 | .anyframe_type, |
test/behavior/memset.zig+18| ... | @@ -135,3 +135,21 @@ test "memset with large array element, comptime known" { | ... | @@ -135,3 +135,21 @@ test "memset with large array element, comptime known" { |
| 135 | for (buf[3]) |elem| try expect(elem == 0); | 135 | for (buf[3]) |elem| try expect(elem == 0); |
| 136 | for (buf[4]) |elem| try expect(elem == 0); | 136 | for (buf[4]) |elem| try expect(elem == 0); |
| 137 | } | 137 | } |
| 138 | |||
| 139 | test "@memset provides result type" { | ||
| 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | ||
| 143 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 144 | |||
| 145 | const S = struct { x: u32 }; | ||
| 146 | |||
| 147 | var buf1: [5]S = undefined; | ||
| 148 | @memset(&buf1, .{ .x = @intCast(12) }); | ||
| 149 | |||
| 150 | var buf2: [5]S = undefined; | ||
| 151 | @memset(@as([]S, &buf2), .{ .x = @intCast(34) }); | ||
| 152 | |||
| 153 | for (buf1) |s| try expect(s.x == 12); | ||
| 154 | for (buf2) |s| try expect(s.x == 34); | ||
| 155 | } |