authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-07-29 06:22:29+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-09 19:46:58+01:00
log93e53d1e00793d769d4ee39b3cbfd0c88257687d
tree615f4e4fa503210282bd0bdf313ff1f7210bceb0
parent6917a8c25824d12f00327171b583d6cd9a830c29
signaturelock-open Commit is signed but in an unrecognized format.

compiler: fix crash on invalid result type for `@splat`

This introduces a new ZIR instruction, `vec_elem_type`. Co-Authored-By: Ali Chraghi <alichraghi@proton.me> Resolves: #16567

5 files changed, 36 insertions(+), 7 deletions(-)

src/AstGen.zig+2-7
......@@ -2569,6 +2569,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
25692569 .array_type_sentinel,
25702570 .elem_type_index,
25712571 .elem_type,
2572 .vector_elem_type,
25722573 .vector_type,
25732574 .indexable_ptr_len,
25742575 .anyframe_type,
......@@ -8624,13 +8625,7 @@ fn builtinCall(
86248625
86258626 .splat => {
86268627 const result_type = try ri.rl.resultType(gz, node, "@splat");
8627 const elem_type = try gz.add(.{
8628 .tag = .elem_type_index,
8629 .data = .{ .bin = .{
8630 .lhs = result_type,
8631 .rhs = @as(Zir.Inst.Ref, @enumFromInt(0)),
8632 } },
8633 });
8628 const elem_type = try gz.addUnNode(.vector_elem_type, result_type, node);
86348629 const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]);
86358630 const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{
86368631 .lhs = result_type,
src/Sema.zig+18
......@@ -1022,6 +1022,7 @@ fn analyzeBodyInner(
10221022 .elem_val_node => try sema.zirElemValNode(block, inst),
10231023 .elem_type_index => try sema.zirElemTypeIndex(block, inst),
10241024 .elem_type => try sema.zirElemType(block, inst),
1025 .vector_elem_type => try sema.zirVectorElemType(block, inst),
10251026 .enum_literal => try sema.zirEnumLiteral(block, inst),
10261027 .int_from_enum => try sema.zirIntFromEnum(block, inst),
10271028 .enum_from_int => try sema.zirEnumFromInt(block, inst),
......@@ -7804,6 +7805,23 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
78047805 return sema.addType(ptr_ty.childType(mod));
78057806}
78067807
7808fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
7809 const mod = sema.mod;
7810 const un_node = sema.code.instructions.items(.data)[inst].un_node;
7811 const vec_ty = sema.resolveType(block, .unneeded, un_node.operand) catch |err| switch (err) {
7812 // Since this is a ZIR instruction that returns a type, encountering
7813 // generic poison should not result in a failed compilation, but the
7814 // generic poison type. This prevents unnecessary failures when
7815 // constructing types at compile-time.
7816 error.GenericPoison => return .generic_poison_type,
7817 else => |e| return e,
7818 };
7819 if (!vec_ty.isVector(mod)) {
7820 return sema.fail(block, un_node.src(), "expected vector type, found '{}'", .{vec_ty.fmt(mod)});
7821 }
7822 return sema.addType(vec_ty.childType(mod));
7823}
7824
78077825fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
78087826 const mod = sema.mod;
78097827 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
src/Zir.zig+6
......@@ -248,6 +248,9 @@ pub const Inst = struct {
248248 /// Given a pointer type, returns its element type.
249249 /// Uses the `un_node` field.
250250 elem_type,
251 /// Given a vector type, returns its element type.
252 /// Uses the `un_node` field.
253 vector_elem_type,
251254 /// Given a pointer to an indexable object, returns the len property. This is
252255 /// used by for loops. This instruction also emits a for-loop specific compile
253256 /// error if the indexable object is not indexable.
......@@ -1029,6 +1032,7 @@ pub const Inst = struct {
10291032 .vector_type,
10301033 .elem_type_index,
10311034 .elem_type,
1035 .vector_elem_type,
10321036 .indexable_ptr_len,
10331037 .anyframe_type,
10341038 .as,
......@@ -1334,6 +1338,7 @@ pub const Inst = struct {
13341338 .vector_type,
13351339 .elem_type_index,
13361340 .elem_type,
1341 .vector_elem_type,
13371342 .indexable_ptr_len,
13381343 .anyframe_type,
13391344 .as,
......@@ -1565,6 +1570,7 @@ pub const Inst = struct {
15651570 .vector_type = .pl_node,
15661571 .elem_type_index = .bin,
15671572 .elem_type = .un_node,
1573 .vector_elem_type = .un_node,
15681574 .indexable_ptr_len = .un_node,
15691575 .anyframe_type = .un_node,
15701576 .as = .bin,
src/print_zir.zig+1
......@@ -155,6 +155,7 @@ const Writer = struct {
155155 .alloc_mut,
156156 .alloc_comptime_mut,
157157 .elem_type,
158 .vector_elem_type,
158159 .indexable_ptr_len,
159160 .anyframe_type,
160161 .bit_not,
test/cases/compile_errors/splat_result_type_non_vector.zig created+9
......@@ -0,0 +1,9 @@
1export fn f() void {
2 _ = @as(u32, @splat(5));
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:18: error: expected vector type, found 'u32'