| ... | ... | @@ -22120,7 +22120,6 @@ pub const PanicId = enum { |
| 22120 | 22120 | shr_overflow, |
| 22121 | 22121 | divide_by_zero, |
| 22122 | 22122 | exact_division_remainder, |
| 22123 | | /// TODO make this call `std.builtin.panicInactiveUnionField`. |
| 22124 | 22123 | inactive_union_field, |
| 22125 | 22124 | integer_part_out_of_bounds, |
| 22126 | 22125 | corrupt_switch, |
| ... | ... | @@ -22296,90 +22295,40 @@ fn panicUnwrapError( |
| 22296 | 22295 | fn panicIndexOutOfBounds( |
| 22297 | 22296 | sema: *Sema, |
| 22298 | 22297 | parent_block: *Block, |
| 22299 | | src: LazySrcLoc, |
| 22300 | 22298 | index: Air.Inst.Ref, |
| 22301 | 22299 | len: Air.Inst.Ref, |
| 22302 | 22300 | cmp_op: Air.Inst.Tag, |
| 22303 | 22301 | ) !void { |
| 22304 | 22302 | assert(!parent_block.is_comptime); |
| 22305 | 22303 | const ok = try parent_block.addBinOp(cmp_op, index, len); |
| 22306 | | const gpa = sema.gpa; |
| 22307 | | |
| 22308 | | var fail_block: Block = .{ |
| 22309 | | .parent = parent_block, |
| 22310 | | .sema = sema, |
| 22311 | | .src_decl = parent_block.src_decl, |
| 22312 | | .namespace = parent_block.namespace, |
| 22313 | | .wip_capture_scope = parent_block.wip_capture_scope, |
| 22314 | | .instructions = .{}, |
| 22315 | | .inlining = parent_block.inlining, |
| 22316 | | .is_comptime = false, |
| 22317 | | }; |
| 22318 | | |
| 22319 | | defer fail_block.instructions.deinit(gpa); |
| 22320 | | |
| 22321 | | { |
| 22322 | | const this_feature_is_implemented_in_the_backend = |
| 22323 | | sema.mod.comp.bin_file.options.use_llvm; |
| 22324 | | |
| 22325 | | if (!this_feature_is_implemented_in_the_backend) { |
| 22326 | | // TODO implement this feature in all the backends and then delete this branch |
| 22327 | | _ = try fail_block.addNoOp(.breakpoint); |
| 22328 | | _ = try fail_block.addNoOp(.unreach); |
| 22329 | | } else { |
| 22330 | | const panic_fn = try sema.getBuiltin("panicOutOfBounds"); |
| 22331 | | const args: [2]Air.Inst.Ref = .{ index, len }; |
| 22332 | | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); |
| 22333 | | } |
| 22334 | | } |
| 22335 | | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22304 | try sema.safetyPanicFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); |
| 22336 | 22305 | } |
| 22337 | 22306 | |
| 22338 | 22307 | fn panicStartLargerThanEnd( |
| 22339 | 22308 | sema: *Sema, |
| 22340 | 22309 | parent_block: *Block, |
| 22341 | | src: LazySrcLoc, |
| 22342 | 22310 | start: Air.Inst.Ref, |
| 22343 | 22311 | end: Air.Inst.Ref, |
| 22344 | 22312 | ) !void { |
| 22345 | 22313 | assert(!parent_block.is_comptime); |
| 22346 | 22314 | 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; |
| 22315 | try sema.safetyPanicFormatted(parent_block, ok, "panicStartGreaterThanEnd", &.{ start, end }); |
| 22316 | } |
| 22365 | 22317 | |
| 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); |
| 22318 | fn panicInactiveUnionField( |
| 22319 | sema: *Sema, |
| 22320 | parent_block: *Block, |
| 22321 | active_tag: Air.Inst.Ref, |
| 22322 | wanted_tag: Air.Inst.Ref, |
| 22323 | ) !void { |
| 22324 | assert(!parent_block.is_comptime); |
| 22325 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 22326 | try sema.safetyPanicFormatted(parent_block, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); |
| 22377 | 22327 | } |
| 22378 | 22328 | |
| 22379 | 22329 | fn panicSentinelMismatch( |
| 22380 | 22330 | sema: *Sema, |
| 22381 | 22331 | parent_block: *Block, |
| 22382 | | src: LazySrcLoc, |
| 22383 | 22332 | maybe_sentinel: ?Value, |
| 22384 | 22333 | sentinel_ty: Type, |
| 22385 | 22334 | ptr: Air.Inst.Ref, |
| ... | ... | @@ -22413,9 +22362,20 @@ fn panicSentinelMismatch( |
| 22413 | 22362 | else { |
| 22414 | 22363 | const panic_fn = try sema.getBuiltin("checkNonScalarSentinel"); |
| 22415 | 22364 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; |
| 22416 | | _ = try sema.analyzeCall(parent_block, panic_fn, src, src, .auto, false, &args, null); |
| 22365 | _ = try sema.analyzeCall(parent_block, panic_fn, sema.src, sema.src, .auto, false, &args, null); |
| 22417 | 22366 | return; |
| 22418 | 22367 | }; |
| 22368 | |
| 22369 | try sema.safetyPanicFormatted(parent_block, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); |
| 22370 | } |
| 22371 | |
| 22372 | fn safetyPanicFormatted( |
| 22373 | sema: *Sema, |
| 22374 | parent_block: *Block, |
| 22375 | ok: Air.Inst.Ref, |
| 22376 | func: []const u8, |
| 22377 | args: []const Air.Inst.Ref, |
| 22378 | ) CompileError!void { |
| 22419 | 22379 | const gpa = sema.gpa; |
| 22420 | 22380 | |
| 22421 | 22381 | var fail_block: Block = .{ |
| ... | ... | @@ -22440,9 +22400,8 @@ fn panicSentinelMismatch( |
| 22440 | 22400 | _ = try fail_block.addNoOp(.breakpoint); |
| 22441 | 22401 | _ = try fail_block.addNoOp(.unreach); |
| 22442 | 22402 | } else { |
| 22443 | | const panic_fn = try sema.getBuiltin("panicSentinelMismatch"); |
| 22444 | | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; |
| 22445 | | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); |
| 22403 | const panic_fn = try sema.getBuiltin(func); |
| 22404 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); |
| 22446 | 22405 | } |
| 22447 | 22406 | } |
| 22448 | 22407 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | ... | @@ -23465,8 +23424,7 @@ fn unionFieldPtr( |
| 23465 | 23424 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 23466 | 23425 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| 23467 | 23426 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val); |
| 23468 | | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 23469 | | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 23427 | try sema.panicInactiveUnionField(block, active_tag, wanted_tag); |
| 23470 | 23428 | } |
| 23471 | 23429 | if (field.ty.zigTypeTag() == .NoReturn) { |
| 23472 | 23430 | _ = try block.addNoOp(.unreach); |
| ... | ... | @@ -23537,8 +23495,7 @@ fn unionFieldVal( |
| 23537 | 23495 | const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 23538 | 23496 | const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val); |
| 23539 | 23497 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval); |
| 23540 | | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 23541 | | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 23498 | try sema.panicInactiveUnionField(block, active_tag, wanted_tag); |
| 23542 | 23499 | } |
| 23543 | 23500 | if (field.ty.zigTypeTag() == .NoReturn) { |
| 23544 | 23501 | _ = try block.addNoOp(.unreach); |
| ... | ... | @@ -23849,7 +23806,7 @@ fn elemValArray( |
| 23849 | 23806 | if (maybe_index_val == null) { |
| 23850 | 23807 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); |
| 23851 | 23808 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; |
| 23852 | | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); |
| 23809 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23853 | 23810 | } |
| 23854 | 23811 | } |
| 23855 | 23812 | return block.addBinOp(.array_elem_val, array, elem_index); |
| ... | ... | @@ -23910,7 +23867,7 @@ fn elemPtrArray( |
| 23910 | 23867 | if (block.wantSafety() and offset == null) { |
| 23911 | 23868 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); |
| 23912 | 23869 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; |
| 23913 | | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); |
| 23870 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23914 | 23871 | } |
| 23915 | 23872 | |
| 23916 | 23873 | return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty); |
| ... | ... | @@ -23966,7 +23923,7 @@ fn elemValSlice( |
| 23966 | 23923 | else |
| 23967 | 23924 | try block.addTyOp(.slice_len, Type.usize, slice); |
| 23968 | 23925 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 23969 | | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); |
| 23926 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23970 | 23927 | } |
| 23971 | 23928 | try sema.queueFullTypeResolution(sema.typeOf(slice)); |
| 23972 | 23929 | return block.addBinOp(.slice_elem_val, slice, elem_index); |
| ... | ... | @@ -24025,7 +23982,7 @@ fn elemPtrSlice( |
| 24025 | 23982 | break :len try block.addTyOp(.slice_len, Type.usize, slice); |
| 24026 | 23983 | }; |
| 24027 | 23984 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 24028 | | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); |
| 23985 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 24029 | 23986 | } |
| 24030 | 23987 | return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty); |
| 24031 | 23988 | } |
| ... | ... | @@ -28072,7 +28029,7 @@ fn analyzeSlice( |
| 28072 | 28029 | |
| 28073 | 28030 | if (block.wantSafety() and !block.is_comptime) { |
| 28074 | 28031 | // requirement: start <= end |
| 28075 | | try sema.panicStartLargerThanEnd(block, src, start, end); |
| 28032 | try sema.panicStartLargerThanEnd(block, start, end); |
| 28076 | 28033 | } |
| 28077 | 28034 | const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); |
| 28078 | 28035 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| ... | ... | @@ -28116,11 +28073,11 @@ fn analyzeSlice( |
| 28116 | 28073 | else |
| 28117 | 28074 | end; |
| 28118 | 28075 | |
| 28119 | | try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte); |
| 28076 | try sema.panicIndexOutOfBounds(block, actual_end, actual_len, .cmp_lte); |
| 28120 | 28077 | } |
| 28121 | 28078 | |
| 28122 | 28079 | // requirement: result[new_len] == slice_sentinel |
| 28123 | | try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len); |
| 28080 | try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len); |
| 28124 | 28081 | } |
| 28125 | 28082 | return result; |
| 28126 | 28083 | }; |
| ... | ... | @@ -28184,11 +28141,11 @@ fn analyzeSlice( |
| 28184 | 28141 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) |
| 28185 | 28142 | else |
| 28186 | 28143 | end; |
| 28187 | | try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte); |
| 28144 | try sema.panicIndexOutOfBounds(block, actual_end, len_inst, .cmp_lte); |
| 28188 | 28145 | } |
| 28189 | 28146 | |
| 28190 | 28147 | // requirement: start <= end |
| 28191 | | try sema.panicIndexOutOfBounds(block, src, start, end, .cmp_lte); |
| 28148 | try sema.panicIndexOutOfBounds(block, start, end, .cmp_lte); |
| 28192 | 28149 | } |
| 28193 | 28150 | const result = try block.addInst(.{ |
| 28194 | 28151 | .tag = .slice, |
| ... | ... | @@ -28202,7 +28159,7 @@ fn analyzeSlice( |
| 28202 | 28159 | }); |
| 28203 | 28160 | if (block.wantSafety()) { |
| 28204 | 28161 | // requirement: result[new_len] == slice_sentinel |
| 28205 | | try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len); |
| 28162 | try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len); |
| 28206 | 28163 | } |
| 28207 | 28164 | return result; |
| 28208 | 28165 | } |