| author | |
| committer | |
| log | 3b2e25ed8718d8aee085497886967fa21a9697cc |
| tree | 1596615c3300c979757de0127f42554f73ffc267 |
| parent | 8b734380f9e900826b1a9cb9804887035f2fe085 |
lead to a Use-After-Free in backend codgen2 files changed, 18 insertions(+), 11 deletions(-)
src/AstGen.zig+10-4| ... | @@ -634,18 +634,24 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -634,18 +634,24 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 634 | 634 | ||
| 635 | return simpleBinOp(gz, scope, rl, node, .bit_and); | 635 | return simpleBinOp(gz, scope, rl, node, .bit_and); |
| 636 | }, | 636 | }, |
| 637 | .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or), | ||
| 638 | .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor), | ||
| 639 | 637 | ||
| 638 | .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or), | ||
| 639 | .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor), | ||
| 640 | .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq), | 640 | .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq), |
| 641 | .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq), | 641 | .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq), |
| 642 | .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt), | 642 | .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt), |
| 643 | .greater_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_gte), | 643 | .greater_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_gte), |
| 644 | .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt), | 644 | .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt), |
| 645 | .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte), | 645 | .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte), |
| 646 | |||
| 647 | .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat), | 646 | .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat), |
| 648 | .array_mult => return simpleBinOp(gz, scope, rl, node, .array_mul), | 647 | |
| 648 | .array_mult => { | ||
| 649 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.Bin{ | ||
| 650 | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), | ||
| 651 | .rhs = try comptimeExpr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs), | ||
| 652 | }); | ||
| 653 | return rvalue(gz, rl, result, node); | ||
| 654 | }, | ||
| 649 | 655 | ||
| 650 | .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type), | 656 | .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type), |
| 651 | .merge_error_sets => return simpleBinOp(gz, scope, rl, node, .merge_error_sets), | 657 | .merge_error_sets => return simpleBinOp(gz, scope, rl, node, .merge_error_sets), |
src/Sema.zig+8-7| ... | @@ -6945,11 +6945,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -6945,11 +6945,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 6945 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 6945 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 6946 | 6946 | ||
| 6947 | // In `**` rhs has to be comptime-known, but lhs can be runtime-known | 6947 | // In `**` rhs has to be comptime-known, but lhs can be runtime-known |
| 6948 | const tomulby = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize); | 6948 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize); |
| 6949 | const mulinfo = getArrayCatInfo(lhs_ty) orelse | 6949 | const mulinfo = getArrayCatInfo(lhs_ty) orelse |
| 6950 | return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); | 6950 | return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); |
| 6951 | 6951 | ||
| 6952 | const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch | 6952 | const final_len = std.math.mul(u64, mulinfo.len, factor) catch |
| 6953 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); | 6953 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |
| 6954 | const final_len_including_sent = final_len + @boolToInt(mulinfo.sentinel != null); | 6954 | const final_len_including_sent = final_len + @boolToInt(mulinfo.sentinel != null); |
| 6955 | 6955 | ||
| ... | @@ -6961,24 +6961,25 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -6961,24 +6961,25 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 6961 | const final_ty = if (mulinfo.sentinel) |sent| | 6961 | const final_ty = if (mulinfo.sentinel) |sent| |
| 6962 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ | 6962 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ |
| 6963 | .len = final_len, | 6963 | .len = final_len, |
| 6964 | .elem_type = mulinfo.elem_type, | 6964 | .elem_type = try mulinfo.elem_type.copy(anon_decl.arena()), |
| 6965 | .sentinel = sent, | 6965 | .sentinel = try sent.copy(anon_decl.arena()), |
| 6966 | }) | 6966 | }) |
| 6967 | else | 6967 | else |
| 6968 | try Type.Tag.array.create(anon_decl.arena(), .{ | 6968 | try Type.Tag.array.create(anon_decl.arena(), .{ |
| 6969 | .len = final_len, | 6969 | .len = final_len, |
| 6970 | .elem_type = mulinfo.elem_type, | 6970 | .elem_type = try mulinfo.elem_type.copy(anon_decl.arena()), |
| 6971 | }); | 6971 | }); |
| 6972 | const buf = try anon_decl.arena().alloc(Value, final_len_including_sent); | 6972 | const buf = try anon_decl.arena().alloc(Value, final_len_including_sent); |
| 6973 | 6973 | ||
| 6974 | // handles the optimisation where arr.len == 0 : [_]T { X } ** N | 6974 | // Optimization for the common pattern of a single element repeated N times, such |
| 6975 | // as zero-filling a byte array. | ||
| 6975 | const val = if (mulinfo.len == 1) blk: { | 6976 | const val = if (mulinfo.len == 1) blk: { |
| 6976 | const copied_val = try (try lhs_sub_val.elemValue(sema.arena, 0)).copy(anon_decl.arena()); | 6977 | const copied_val = try (try lhs_sub_val.elemValue(sema.arena, 0)).copy(anon_decl.arena()); |
| 6977 | break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val); | 6978 | break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val); |
| 6978 | } else blk: { | 6979 | } else blk: { |
| 6979 | // the actual loop | 6980 | // the actual loop |
| 6980 | var i: u64 = 0; | 6981 | var i: u64 = 0; |
| 6981 | while (i < tomulby) : (i += 1) { | 6982 | while (i < factor) : (i += 1) { |
| 6982 | var j: u64 = 0; | 6983 | var j: u64 = 0; |
| 6983 | while (j < mulinfo.len) : (j += 1) { | 6984 | while (j < mulinfo.len) : (j += 1) { |
| 6984 | const val = try lhs_sub_val.elemValue(sema.arena, j); | 6985 | const val = try lhs_sub_val.elemValue(sema.arena, j); |