| ... | ... | @@ -12437,7 +12437,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 12437 | 12437 | else |
| 12438 | 12438 | try sema.resolveInst(.zero); |
| 12439 | 12439 | |
| 12440 | | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src); |
| 12440 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); |
| 12441 | 12441 | } |
| 12442 | 12442 | |
| 12443 | 12443 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -12460,7 +12460,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 12460 | 12460 | else |
| 12461 | 12461 | try sema.resolveInst(.zero); |
| 12462 | 12462 | |
| 12463 | | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src); |
| 12463 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); |
| 12464 | 12464 | } |
| 12465 | 12465 | |
| 12466 | 12466 | fn zirArithmetic( |
| ... | ... | @@ -12480,7 +12480,7 @@ fn zirArithmetic( |
| 12480 | 12480 | const lhs = try sema.resolveInst(extra.lhs); |
| 12481 | 12481 | const rhs = try sema.resolveInst(extra.rhs); |
| 12482 | 12482 | |
| 12483 | | return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src); |
| 12483 | return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, true); |
| 12484 | 12484 | } |
| 12485 | 12485 | |
| 12486 | 12486 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -13776,6 +13776,7 @@ fn analyzeArithmetic( |
| 13776 | 13776 | src: LazySrcLoc, |
| 13777 | 13777 | lhs_src: LazySrcLoc, |
| 13778 | 13778 | rhs_src: LazySrcLoc, |
| 13779 | want_safety: bool, |
| 13779 | 13780 | ) CompileError!Air.Inst.Ref { |
| 13780 | 13781 | const lhs_ty = sema.typeOf(lhs); |
| 13781 | 13782 | const rhs_ty = sema.typeOf(rhs); |
| ... | ... | @@ -14204,7 +14205,7 @@ fn analyzeArithmetic( |
| 14204 | 14205 | }; |
| 14205 | 14206 | |
| 14206 | 14207 | try sema.requireRuntimeBlock(block, src, rs.src); |
| 14207 | | if (block.wantSafety()) { |
| 14208 | if (block.wantSafety() and want_safety) { |
| 14208 | 14209 | if (scalar_tag == .Int) { |
| 14209 | 14210 | const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { |
| 14210 | 14211 | .add => .add_with_overflow, |
| ... | ... | @@ -22334,6 +22335,47 @@ fn panicIndexOutOfBounds( |
| 22334 | 22335 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22335 | 22336 | } |
| 22336 | 22337 | |
| 22338 | fn panicStartLargerThanEnd( |
| 22339 | sema: *Sema, |
| 22340 | parent_block: *Block, |
| 22341 | src: LazySrcLoc, |
| 22342 | start: Air.Inst.Ref, |
| 22343 | end: Air.Inst.Ref, |
| 22344 | ) !void { |
| 22345 | assert(!parent_block.is_comptime); |
| 22346 | const ok = try parent_block.addBinOp(.cmp_lte, start, end); |
| 22347 | const gpa = sema.gpa; |
| 22348 | |
| 22349 | var fail_block: Block = .{ |
| 22350 | .parent = parent_block, |
| 22351 | .sema = sema, |
| 22352 | .src_decl = parent_block.src_decl, |
| 22353 | .namespace = parent_block.namespace, |
| 22354 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 22355 | .instructions = .{}, |
| 22356 | .inlining = parent_block.inlining, |
| 22357 | .is_comptime = false, |
| 22358 | }; |
| 22359 | |
| 22360 | defer fail_block.instructions.deinit(gpa); |
| 22361 | |
| 22362 | { |
| 22363 | const this_feature_is_implemented_in_the_backend = |
| 22364 | sema.mod.comp.bin_file.options.use_llvm; |
| 22365 | |
| 22366 | if (!this_feature_is_implemented_in_the_backend) { |
| 22367 | // TODO implement this feature in all the backends and then delete this branch |
| 22368 | _ = try fail_block.addNoOp(.breakpoint); |
| 22369 | _ = try fail_block.addNoOp(.unreach); |
| 22370 | } else { |
| 22371 | const panic_fn = try sema.getBuiltin("panicStartGreaterThanEnd"); |
| 22372 | const args: [2]Air.Inst.Ref = .{ start, end }; |
| 22373 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); |
| 22374 | } |
| 22375 | } |
| 22376 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22377 | } |
| 22378 | |
| 22337 | 22379 | fn panicSentinelMismatch( |
| 22338 | 22380 | sema: *Sema, |
| 22339 | 22381 | parent_block: *Block, |
| ... | ... | @@ -28028,7 +28070,11 @@ fn analyzeSlice( |
| 28028 | 28070 | } |
| 28029 | 28071 | } |
| 28030 | 28072 | |
| 28031 | | const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src); |
| 28073 | if (block.wantSafety() and !block.is_comptime) { |
| 28074 | // requirement: start <= end |
| 28075 | try sema.panicStartLargerThanEnd(block, src, start, end); |
| 28076 | } |
| 28077 | const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); |
| 28032 | 28078 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| 28033 | 28079 | |
| 28034 | 28080 | const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data; |
| ... | ... | @@ -28063,10 +28109,10 @@ fn analyzeSlice( |
| 28063 | 28109 | const actual_len = if (slice_ty.sentinel() == null) |
| 28064 | 28110 | slice_len_inst |
| 28065 | 28111 | else |
| 28066 | | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); |
| 28112 | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| 28067 | 28113 | |
| 28068 | 28114 | const actual_end = if (slice_sentinel != null) |
| 28069 | | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) |
| 28115 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) |
| 28070 | 28116 | else |
| 28071 | 28117 | end; |
| 28072 | 28118 | |
| ... | ... | @@ -28131,11 +28177,11 @@ fn analyzeSlice( |
| 28131 | 28177 | if (slice_ty.sentinel() == null) break :blk slice_len_inst; |
| 28132 | 28178 | |
| 28133 | 28179 | // we have to add one because slice lengths don't include the sentinel |
| 28134 | | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); |
| 28180 | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| 28135 | 28181 | } else null; |
| 28136 | 28182 | if (opt_len_inst) |len_inst| { |
| 28137 | 28183 | const actual_end = if (slice_sentinel != null) |
| 28138 | | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) |
| 28184 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) |
| 28139 | 28185 | else |
| 28140 | 28186 | end; |
| 28141 | 28187 | try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte); |