| ... | @@ -667,9 +667,9 @@ pub const Block = struct { | ... | @@ -667,9 +667,9 @@ pub const Block = struct { |
| 667 | return result_index; | 667 | return result_index; |
| 668 | } | 668 | } |
| 669 | | 669 | |
| 670 | fn addUnreachable(block: *Block, src: LazySrcLoc, safety_check: bool) !void { | 670 | fn addUnreachable(block: *Block, safety_check: bool) !void { |
| 671 | if (safety_check and block.wantSafety()) { | 671 | if (safety_check and block.wantSafety()) { |
| 672 | _ = try block.sema.safetyPanic(block, src, .unreach); | 672 | try block.sema.safetyPanic(block, .unreach); |
| 673 | } else { | 673 | } else { |
| 674 | _ = try block.addNoOp(.unreach); | 674 | _ = try block.addNoOp(.unreach); |
| 675 | } | 675 | } |
| ... | @@ -5003,7 +5003,8 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo | ... | @@ -5003,7 +5003,8 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo |
| 5003 | if (block.is_comptime or force_comptime) { | 5003 | if (block.is_comptime or force_comptime) { |
| 5004 | return sema.fail(block, src, "encountered @panic at comptime", .{}); | 5004 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 5005 | } | 5005 | } |
| 5006 | return sema.panicWithMsg(block, src, msg_inst); | 5006 | try sema.panicWithMsg(block, src, msg_inst); |
| | 5007 | return always_noreturn; |
| 5007 | } | 5008 | } |
| 5008 | | 5009 | |
| 5009 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5010 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5390,7 +5391,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -5390,7 +5391,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5390 | const container_namespace = container_ty.getNamespace().?; | 5391 | const container_namespace = container_ty.getNamespace().?; |
| 5391 | | 5392 | |
| 5392 | const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false); | 5393 | const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false); |
| 5393 | break :index_blk maybe_index.?; // AstGen would produce error in case of unidentified name | 5394 | break :index_blk maybe_index orelse |
| | 5395 | return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name); |
| 5394 | } else try sema.lookupIdentifier(block, operand_src, decl_name); | 5396 | } else try sema.lookupIdentifier(block, operand_src, decl_name); |
| 5395 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { | 5397 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { |
| 5396 | error.NeededSourceLocation => { | 5398 | error.NeededSourceLocation => { |
| ... | @@ -7962,7 +7964,7 @@ fn analyzeErrUnionPayload( | ... | @@ -7962,7 +7964,7 @@ fn analyzeErrUnionPayload( |
| 7962 | if (safety_check and block.wantSafety() and | 7964 | if (safety_check and block.wantSafety() and |
| 7963 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) | 7965 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) |
| 7964 | { | 7966 | { |
| 7965 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err); | 7967 | try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err); |
| 7966 | } | 7968 | } |
| 7967 | | 7969 | |
| 7968 | return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand); | 7970 | return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand); |
| ... | @@ -8047,7 +8049,7 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -8047,7 +8049,7 @@ fn analyzeErrUnionPayloadPtr( |
| 8047 | if (safety_check and block.wantSafety() and | 8049 | if (safety_check and block.wantSafety() and |
| 8048 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) | 8050 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) |
| 8049 | { | 8051 | { |
| 8050 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); | 8052 | try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); |
| 8051 | } | 8053 | } |
| 8052 | | 8054 | |
| 8053 | const air_tag: Air.Inst.Tag = if (initializing) | 8055 | const air_tag: Air.Inst.Tag = if (initializing) |
| ... | @@ -8709,6 +8711,9 @@ fn analyzeParameter( | ... | @@ -8709,6 +8711,9 @@ fn analyzeParameter( |
| 8709 | }); | 8711 | }); |
| 8710 | errdefer msg.destroy(sema.gpa); | 8712 | errdefer msg.destroy(sema.gpa); |
| 8711 | | 8713 | |
| | 8714 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 8715 | try sema.explainWhyTypeIsComptime(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty); |
| | 8716 | |
| 8712 | try sema.addDeclaredHereNote(msg, param.ty); | 8717 | try sema.addDeclaredHereNote(msg, param.ty); |
| 8713 | break :msg msg; | 8718 | break :msg msg; |
| 8714 | }; | 8719 | }; |
| ... | @@ -9539,7 +9544,7 @@ fn zirSwitchCapture( | ... | @@ -9539,7 +9544,7 @@ fn zirSwitchCapture( |
| 9539 | .ErrorSet => if (block.switch_else_err_ty) |some| { | 9544 | .ErrorSet => if (block.switch_else_err_ty) |some| { |
| 9540 | return sema.bitCast(block, some, operand, operand_src); | 9545 | return sema.bitCast(block, some, operand, operand_src); |
| 9541 | } else { | 9546 | } else { |
| 9542 | try block.addUnreachable(operand_src, false); | 9547 | try block.addUnreachable(false); |
| 9543 | return Air.Inst.Ref.unreachable_value; | 9548 | return Air.Inst.Ref.unreachable_value; |
| 9544 | }, | 9549 | }, |
| 9545 | else => return operand, | 9550 | else => return operand, |
| ... | @@ -10972,7 +10977,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10972,7 +10977,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10972 | // that it is unreachable. | 10977 | // that it is unreachable. |
| 10973 | if (case_block.wantSafety()) { | 10978 | if (case_block.wantSafety()) { |
| 10974 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); | 10979 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); |
| 10975 | _ = try sema.safetyPanic(&case_block, src, .corrupt_switch); | 10980 | try sema.safetyPanic(&case_block, .corrupt_switch); |
| 10976 | } else { | 10981 | } else { |
| 10977 | _ = try case_block.addNoOp(.unreach); | 10982 | _ = try case_block.addNoOp(.unreach); |
| 10978 | } | 10983 | } |
| ... | @@ -11301,6 +11306,11 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op | ... | @@ -11301,6 +11306,11 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op |
| 11301 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; | 11306 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; |
| 11302 | const src = inst_data.src(); | 11307 | const src = inst_data.src(); |
| 11303 | | 11308 | |
| | 11309 | if (!sema.mod.comp.formatted_panics) { |
| | 11310 | try sema.safetyPanic(block, .unwrap_error); |
| | 11311 | return true; |
| | 11312 | } |
| | 11313 | |
| 11304 | const panic_fn = try sema.getBuiltin("panicUnwrapError"); | 11314 | const panic_fn = try sema.getBuiltin("panicUnwrapError"); |
| 11305 | const err_return_trace = try sema.getErrorReturnTrace(block); | 11315 | const err_return_trace = try sema.getErrorReturnTrace(block); |
| 11306 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; | 11316 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; |
| ... | @@ -12437,7 +12447,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -12437,7 +12447,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 12437 | else | 12447 | else |
| 12438 | try sema.resolveInst(.zero); | 12448 | try sema.resolveInst(.zero); |
| 12439 | | 12449 | |
| 12440 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src); | 12450 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); |
| 12441 | } | 12451 | } |
| 12442 | | 12452 | |
| 12443 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 12453 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -12460,7 +12470,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -12460,7 +12470,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 12460 | else | 12470 | else |
| 12461 | try sema.resolveInst(.zero); | 12471 | try sema.resolveInst(.zero); |
| 12462 | | 12472 | |
| 12463 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src); | 12473 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); |
| 12464 | } | 12474 | } |
| 12465 | | 12475 | |
| 12466 | fn zirArithmetic( | 12476 | fn zirArithmetic( |
| ... | @@ -12480,7 +12490,7 @@ fn zirArithmetic( | ... | @@ -12480,7 +12490,7 @@ fn zirArithmetic( |
| 12480 | const lhs = try sema.resolveInst(extra.lhs); | 12490 | const lhs = try sema.resolveInst(extra.lhs); |
| 12481 | const rhs = try sema.resolveInst(extra.rhs); | 12491 | const rhs = try sema.resolveInst(extra.rhs); |
| 12482 | | 12492 | |
| 12483 | return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src); | 12493 | return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, true); |
| 12484 | } | 12494 | } |
| 12485 | | 12495 | |
| 12486 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 12496 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -13776,6 +13786,7 @@ fn analyzeArithmetic( | ... | @@ -13776,6 +13786,7 @@ fn analyzeArithmetic( |
| 13776 | src: LazySrcLoc, | 13786 | src: LazySrcLoc, |
| 13777 | lhs_src: LazySrcLoc, | 13787 | lhs_src: LazySrcLoc, |
| 13778 | rhs_src: LazySrcLoc, | 13788 | rhs_src: LazySrcLoc, |
| | 13789 | want_safety: bool, |
| 13779 | ) CompileError!Air.Inst.Ref { | 13790 | ) CompileError!Air.Inst.Ref { |
| 13780 | const lhs_ty = sema.typeOf(lhs); | 13791 | const lhs_ty = sema.typeOf(lhs); |
| 13781 | const rhs_ty = sema.typeOf(rhs); | 13792 | const rhs_ty = sema.typeOf(rhs); |
| ... | @@ -14204,7 +14215,7 @@ fn analyzeArithmetic( | ... | @@ -14204,7 +14215,7 @@ fn analyzeArithmetic( |
| 14204 | }; | 14215 | }; |
| 14205 | | 14216 | |
| 14206 | try sema.requireRuntimeBlock(block, src, rs.src); | 14217 | try sema.requireRuntimeBlock(block, src, rs.src); |
| 14207 | if (block.wantSafety()) { | 14218 | if (block.wantSafety() and want_safety) { |
| 14208 | if (scalar_tag == .Int) { | 14219 | if (scalar_tag == .Int) { |
| 14209 | const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { | 14220 | const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { |
| 14210 | .add => .add_with_overflow, | 14221 | .add => .add_with_overflow, |
| ... | @@ -16509,7 +16520,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -16509,7 +16520,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 16509 | return sema.fail(block, src, "reached unreachable code", .{}); | 16520 | return sema.fail(block, src, "reached unreachable code", .{}); |
| 16510 | } | 16521 | } |
| 16511 | // TODO Add compile error for @optimizeFor occurring too late in a scope. | 16522 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| 16512 | try block.addUnreachable(src, true); | 16523 | try block.addUnreachable(true); |
| 16513 | return always_noreturn; | 16524 | return always_noreturn; |
| 16514 | } | 16525 | } |
| 16515 | | 16526 | |
| ... | @@ -17603,11 +17614,11 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -17603,11 +17614,11 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17603 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 17614 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 17604 | const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; | 17615 | const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; |
| 17605 | const ty_src = inst_data.src(); | 17616 | const ty_src = inst_data.src(); |
| 17606 | const field_src = inst_data.src(); | 17617 | const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node }; |
| 17607 | const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type); | 17618 | const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type); |
| 17608 | if (aggregate_ty.tag() == .var_args_param) return sema.addType(aggregate_ty); | 17619 | if (aggregate_ty.tag() == .var_args_param) return sema.addType(aggregate_ty); |
| 17609 | const field_name = sema.code.nullTerminatedString(extra.name_start); | 17620 | const field_name = sema.code.nullTerminatedString(extra.name_start); |
| 17610 | return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src); | 17621 | return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src); |
| 17611 | } | 17622 | } |
| 17612 | | 17623 | |
| 17613 | fn fieldType( | 17624 | fn fieldType( |
| ... | @@ -22119,12 +22130,15 @@ pub const PanicId = enum { | ... | @@ -22119,12 +22130,15 @@ pub const PanicId = enum { |
| 22119 | shr_overflow, | 22130 | shr_overflow, |
| 22120 | divide_by_zero, | 22131 | divide_by_zero, |
| 22121 | exact_division_remainder, | 22132 | exact_division_remainder, |
| 22122 | /// TODO make this call `std.builtin.panicInactiveUnionField`. | | |
| 22123 | inactive_union_field, | 22133 | inactive_union_field, |
| 22124 | integer_part_out_of_bounds, | 22134 | integer_part_out_of_bounds, |
| 22125 | corrupt_switch, | 22135 | corrupt_switch, |
| 22126 | shift_rhs_too_big, | 22136 | shift_rhs_too_big, |
| 22127 | invalid_enum_value, | 22137 | invalid_enum_value, |
| | 22138 | sentinel_mismatch, |
| | 22139 | unwrap_error, |
| | 22140 | index_out_of_bounds, |
| | 22141 | start_index_greater_than_end, |
| 22128 | }; | 22142 | }; |
| 22129 | | 22143 | |
| 22130 | fn addSafetyCheck( | 22144 | fn addSafetyCheck( |
| ... | @@ -22149,12 +22163,7 @@ fn addSafetyCheck( | ... | @@ -22149,12 +22163,7 @@ fn addSafetyCheck( |
| 22149 | | 22163 | |
| 22150 | defer fail_block.instructions.deinit(gpa); | 22164 | defer fail_block.instructions.deinit(gpa); |
| 22151 | | 22165 | |
| 22152 | // This function doesn't actually need a src location but if | 22166 | try sema.safetyPanic(&fail_block, panic_id); |
| 22153 | // the panic function interface ever changes passing `.unneeded` here | | |
| 22154 | // will cause confusing panics. | | |
| 22155 | const src = sema.src; | | |
| 22156 | _ = try sema.safetyPanic(&fail_block, src, panic_id); | | |
| 22157 | | | |
| 22158 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22167 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22159 | } | 22168 | } |
| 22160 | | 22169 | |
| ... | @@ -22218,7 +22227,7 @@ fn panicWithMsg( | ... | @@ -22218,7 +22227,7 @@ fn panicWithMsg( |
| 22218 | block: *Block, | 22227 | block: *Block, |
| 22219 | src: LazySrcLoc, | 22228 | src: LazySrcLoc, |
| 22220 | msg_inst: Air.Inst.Ref, | 22229 | msg_inst: Air.Inst.Ref, |
| 22221 | ) !Zir.Inst.Index { | 22230 | ) !void { |
| 22222 | const mod = sema.mod; | 22231 | const mod = sema.mod; |
| 22223 | const arena = sema.arena; | 22232 | const arena = sema.arena; |
| 22224 | | 22233 | |
| ... | @@ -22229,7 +22238,7 @@ fn panicWithMsg( | ... | @@ -22229,7 +22238,7 @@ fn panicWithMsg( |
| 22229 | // TODO implement this feature in all the backends and then delete this branch | 22238 | // TODO implement this feature in all the backends and then delete this branch |
| 22230 | _ = try block.addNoOp(.breakpoint); | 22239 | _ = try block.addNoOp(.breakpoint); |
| 22231 | _ = try block.addNoOp(.unreach); | 22240 | _ = try block.addNoOp(.unreach); |
| 22232 | return always_noreturn; | 22241 | return; |
| 22233 | } | 22242 | } |
| 22234 | const panic_fn = try sema.getBuiltin("panic"); | 22243 | const panic_fn = try sema.getBuiltin("panic"); |
| 22235 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); | 22244 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| ... | @@ -22245,19 +22254,20 @@ fn panicWithMsg( | ... | @@ -22245,19 +22254,20 @@ fn panicWithMsg( |
| 22245 | ); | 22254 | ); |
| 22246 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; | 22255 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; |
| 22247 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); | 22256 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); |
| 22248 | return always_noreturn; | | |
| 22249 | } | 22257 | } |
| 22250 | | 22258 | |
| 22251 | fn panicUnwrapError( | 22259 | fn panicUnwrapError( |
| 22252 | sema: *Sema, | 22260 | sema: *Sema, |
| 22253 | parent_block: *Block, | 22261 | parent_block: *Block, |
| 22254 | src: LazySrcLoc, | | |
| 22255 | operand: Air.Inst.Ref, | 22262 | operand: Air.Inst.Ref, |
| 22256 | unwrap_err_tag: Air.Inst.Tag, | 22263 | unwrap_err_tag: Air.Inst.Tag, |
| 22257 | is_non_err_tag: Air.Inst.Tag, | 22264 | is_non_err_tag: Air.Inst.Tag, |
| 22258 | ) !void { | 22265 | ) !void { |
| 22259 | assert(!parent_block.is_comptime); | 22266 | assert(!parent_block.is_comptime); |
| 22260 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); | 22267 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); |
| | 22268 | if (!sema.mod.comp.formatted_panics) { |
| | 22269 | return sema.addSafetyCheck(parent_block, ok, .unwrap_error); |
| | 22270 | } |
| 22261 | const gpa = sema.gpa; | 22271 | const gpa = sema.gpa; |
| 22262 | | 22272 | |
| 22263 | var fail_block: Block = .{ | 22273 | var fail_block: Block = .{ |
| ... | @@ -22286,7 +22296,7 @@ fn panicUnwrapError( | ... | @@ -22286,7 +22296,7 @@ fn panicUnwrapError( |
| 22286 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); | 22296 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); |
| 22287 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); | 22297 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); |
| 22288 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; | 22298 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; |
| 22289 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); | 22299 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, &args, null); |
| 22290 | } | 22300 | } |
| 22291 | } | 22301 | } |
| 22292 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22302 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | @@ -22295,49 +22305,49 @@ fn panicUnwrapError( | ... | @@ -22295,49 +22305,49 @@ fn panicUnwrapError( |
| 22295 | fn panicIndexOutOfBounds( | 22305 | fn panicIndexOutOfBounds( |
| 22296 | sema: *Sema, | 22306 | sema: *Sema, |
| 22297 | parent_block: *Block, | 22307 | parent_block: *Block, |
| 22298 | src: LazySrcLoc, | | |
| 22299 | index: Air.Inst.Ref, | 22308 | index: Air.Inst.Ref, |
| 22300 | len: Air.Inst.Ref, | 22309 | len: Air.Inst.Ref, |
| 22301 | cmp_op: Air.Inst.Tag, | 22310 | cmp_op: Air.Inst.Tag, |
| 22302 | ) !void { | 22311 | ) !void { |
| 22303 | assert(!parent_block.is_comptime); | 22312 | assert(!parent_block.is_comptime); |
| 22304 | const ok = try parent_block.addBinOp(cmp_op, index, len); | 22313 | const ok = try parent_block.addBinOp(cmp_op, index, len); |
| 22305 | const gpa = sema.gpa; | 22314 | if (!sema.mod.comp.formatted_panics) { |
| 22306 | | 22315 | return sema.addSafetyCheck(parent_block, ok, .index_out_of_bounds); |
| 22307 | var fail_block: Block = .{ | 22316 | } |
| 22308 | .parent = parent_block, | 22317 | try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); |
| 22309 | .sema = sema, | 22318 | } |
| 22310 | .src_decl = parent_block.src_decl, | | |
| 22311 | .namespace = parent_block.namespace, | | |
| 22312 | .wip_capture_scope = parent_block.wip_capture_scope, | | |
| 22313 | .instructions = .{}, | | |
| 22314 | .inlining = parent_block.inlining, | | |
| 22315 | .is_comptime = false, | | |
| 22316 | }; | | |
| 22317 | | | |
| 22318 | defer fail_block.instructions.deinit(gpa); | | |
| 22319 | | 22319 | |
| 22320 | { | 22320 | fn panicStartLargerThanEnd( |
| 22321 | const this_feature_is_implemented_in_the_backend = | 22321 | sema: *Sema, |
| 22322 | sema.mod.comp.bin_file.options.use_llvm; | 22322 | parent_block: *Block, |
| | 22323 | start: Air.Inst.Ref, |
| | 22324 | end: Air.Inst.Ref, |
| | 22325 | ) !void { |
| | 22326 | assert(!parent_block.is_comptime); |
| | 22327 | const ok = try parent_block.addBinOp(.cmp_lte, start, end); |
| | 22328 | if (!sema.mod.comp.formatted_panics) { |
| | 22329 | return sema.addSafetyCheck(parent_block, ok, .start_index_greater_than_end); |
| | 22330 | } |
| | 22331 | try sema.safetyCheckFormatted(parent_block, ok, "panicStartGreaterThanEnd", &.{ start, end }); |
| | 22332 | } |
| 22323 | | 22333 | |
| 22324 | if (!this_feature_is_implemented_in_the_backend) { | 22334 | fn panicInactiveUnionField( |
| 22325 | // TODO implement this feature in all the backends and then delete this branch | 22335 | sema: *Sema, |
| 22326 | _ = try fail_block.addNoOp(.breakpoint); | 22336 | parent_block: *Block, |
| 22327 | _ = try fail_block.addNoOp(.unreach); | 22337 | active_tag: Air.Inst.Ref, |
| 22328 | } else { | 22338 | wanted_tag: Air.Inst.Ref, |
| 22329 | const panic_fn = try sema.getBuiltin("panicOutOfBounds"); | 22339 | ) !void { |
| 22330 | const args: [2]Air.Inst.Ref = .{ index, len }; | 22340 | assert(!parent_block.is_comptime); |
| 22331 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); | 22341 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 22332 | } | 22342 | if (!sema.mod.comp.formatted_panics) { |
| | 22343 | return sema.addSafetyCheck(parent_block, ok, .inactive_union_field); |
| 22333 | } | 22344 | } |
| 22334 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22345 | try sema.safetyCheckFormatted(parent_block, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); |
| 22335 | } | 22346 | } |
| 22336 | | 22347 | |
| 22337 | fn panicSentinelMismatch( | 22348 | fn panicSentinelMismatch( |
| 22338 | sema: *Sema, | 22349 | sema: *Sema, |
| 22339 | parent_block: *Block, | 22350 | parent_block: *Block, |
| 22340 | src: LazySrcLoc, | | |
| 22341 | maybe_sentinel: ?Value, | 22351 | maybe_sentinel: ?Value, |
| 22342 | sentinel_ty: Type, | 22352 | sentinel_ty: Type, |
| 22343 | ptr: Air.Inst.Ref, | 22353 | ptr: Air.Inst.Ref, |
| ... | @@ -22371,9 +22381,24 @@ fn panicSentinelMismatch( | ... | @@ -22371,9 +22381,24 @@ fn panicSentinelMismatch( |
| 22371 | else { | 22381 | else { |
| 22372 | const panic_fn = try sema.getBuiltin("checkNonScalarSentinel"); | 22382 | const panic_fn = try sema.getBuiltin("checkNonScalarSentinel"); |
| 22373 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; | 22383 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; |
| 22374 | _ = try sema.analyzeCall(parent_block, panic_fn, src, src, .auto, false, &args, null); | 22384 | _ = try sema.analyzeCall(parent_block, panic_fn, sema.src, sema.src, .auto, false, &args, null); |
| 22375 | return; | 22385 | return; |
| 22376 | }; | 22386 | }; |
| | 22387 | |
| | 22388 | if (!sema.mod.comp.formatted_panics) { |
| | 22389 | return sema.addSafetyCheck(parent_block, ok, .sentinel_mismatch); |
| | 22390 | } |
| | 22391 | try sema.safetyCheckFormatted(parent_block, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); |
| | 22392 | } |
| | 22393 | |
| | 22394 | fn safetyCheckFormatted( |
| | 22395 | sema: *Sema, |
| | 22396 | parent_block: *Block, |
| | 22397 | ok: Air.Inst.Ref, |
| | 22398 | func: []const u8, |
| | 22399 | args: []const Air.Inst.Ref, |
| | 22400 | ) CompileError!void { |
| | 22401 | assert(sema.mod.comp.formatted_panics); |
| 22377 | const gpa = sema.gpa; | 22402 | const gpa = sema.gpa; |
| 22378 | | 22403 | |
| 22379 | var fail_block: Block = .{ | 22404 | var fail_block: Block = .{ |
| ... | @@ -22398,9 +22423,8 @@ fn panicSentinelMismatch( | ... | @@ -22398,9 +22423,8 @@ fn panicSentinelMismatch( |
| 22398 | _ = try fail_block.addNoOp(.breakpoint); | 22423 | _ = try fail_block.addNoOp(.breakpoint); |
| 22399 | _ = try fail_block.addNoOp(.unreach); | 22424 | _ = try fail_block.addNoOp(.unreach); |
| 22400 | } else { | 22425 | } else { |
| 22401 | const panic_fn = try sema.getBuiltin("panicSentinelMismatch"); | 22426 | const panic_fn = try sema.getBuiltin(func); |
| 22402 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; | 22427 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); |
| 22403 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); | | |
| 22404 | } | 22428 | } |
| 22405 | } | 22429 | } |
| 22406 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22430 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | @@ -22409,19 +22433,18 @@ fn panicSentinelMismatch( | ... | @@ -22409,19 +22433,18 @@ fn panicSentinelMismatch( |
| 22409 | fn safetyPanic( | 22433 | fn safetyPanic( |
| 22410 | sema: *Sema, | 22434 | sema: *Sema, |
| 22411 | block: *Block, | 22435 | block: *Block, |
| 22412 | src: LazySrcLoc, | | |
| 22413 | panic_id: PanicId, | 22436 | panic_id: PanicId, |
| 22414 | ) CompileError!Zir.Inst.Index { | 22437 | ) CompileError!void { |
| 22415 | const panic_messages_ty = try sema.getBuiltinType("panic_messages"); | 22438 | const panic_messages_ty = try sema.getBuiltinType("panic_messages"); |
| 22416 | const msg_decl_index = (try sema.namespaceLookup( | 22439 | const msg_decl_index = (try sema.namespaceLookup( |
| 22417 | block, | 22440 | block, |
| 22418 | src, | 22441 | sema.src, |
| 22419 | panic_messages_ty.getNamespace().?, | 22442 | panic_messages_ty.getNamespace().?, |
| 22420 | @tagName(panic_id), | 22443 | @tagName(panic_id), |
| 22421 | )).?; | 22444 | )).?; |
| 22422 | | 22445 | |
| 22423 | const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index); | 22446 | const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index); |
| 22424 | return sema.panicWithMsg(block, src, msg_inst); | 22447 | try sema.panicWithMsg(block, sema.src, msg_inst); |
| 22425 | } | 22448 | } |
| 22426 | | 22449 | |
| 22427 | fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { | 22450 | fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| ... | @@ -23423,8 +23446,7 @@ fn unionFieldPtr( | ... | @@ -23423,8 +23446,7 @@ fn unionFieldPtr( |
| 23423 | // TODO would it be better if get_union_tag supported pointers to unions? | 23446 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 23424 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); | 23447 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| 23425 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val); | 23448 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val); |
| 23426 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 23449 | try sema.panicInactiveUnionField(block, active_tag, wanted_tag); |
| 23427 | try sema.addSafetyCheck(block, ok, .inactive_union_field); | | |
| 23428 | } | 23450 | } |
| 23429 | if (field.ty.zigTypeTag() == .NoReturn) { | 23451 | if (field.ty.zigTypeTag() == .NoReturn) { |
| 23430 | _ = try block.addNoOp(.unreach); | 23452 | _ = try block.addNoOp(.unreach); |
| ... | @@ -23495,8 +23517,7 @@ fn unionFieldVal( | ... | @@ -23495,8 +23517,7 @@ fn unionFieldVal( |
| 23495 | const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); | 23517 | const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 23496 | const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val); | 23518 | const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val); |
| 23497 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval); | 23519 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval); |
| 23498 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 23520 | try sema.panicInactiveUnionField(block, active_tag, wanted_tag); |
| 23499 | try sema.addSafetyCheck(block, ok, .inactive_union_field); | | |
| 23500 | } | 23521 | } |
| 23501 | if (field.ty.zigTypeTag() == .NoReturn) { | 23522 | if (field.ty.zigTypeTag() == .NoReturn) { |
| 23502 | _ = try block.addNoOp(.unreach); | 23523 | _ = try block.addNoOp(.unreach); |
| ... | @@ -23807,7 +23828,7 @@ fn elemValArray( | ... | @@ -23807,7 +23828,7 @@ fn elemValArray( |
| 23807 | if (maybe_index_val == null) { | 23828 | if (maybe_index_val == null) { |
| 23808 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); | 23829 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); |
| 23809 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; | 23830 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; |
| 23810 | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); | 23831 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23811 | } | 23832 | } |
| 23812 | } | 23833 | } |
| 23813 | return block.addBinOp(.array_elem_val, array, elem_index); | 23834 | return block.addBinOp(.array_elem_val, array, elem_index); |
| ... | @@ -23868,7 +23889,7 @@ fn elemPtrArray( | ... | @@ -23868,7 +23889,7 @@ fn elemPtrArray( |
| 23868 | if (block.wantSafety() and offset == null) { | 23889 | if (block.wantSafety() and offset == null) { |
| 23869 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); | 23890 | const len_inst = try sema.addIntUnsigned(Type.usize, array_len); |
| 23870 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; | 23891 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; |
| 23871 | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); | 23892 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23872 | } | 23893 | } |
| 23873 | | 23894 | |
| 23874 | return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty); | 23895 | return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty); |
| ... | @@ -23924,7 +23945,7 @@ fn elemValSlice( | ... | @@ -23924,7 +23945,7 @@ fn elemValSlice( |
| 23924 | else | 23945 | else |
| 23925 | try block.addTyOp(.slice_len, Type.usize, slice); | 23946 | try block.addTyOp(.slice_len, Type.usize, slice); |
| 23926 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 23947 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 23927 | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); | 23948 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23928 | } | 23949 | } |
| 23929 | try sema.queueFullTypeResolution(sema.typeOf(slice)); | 23950 | try sema.queueFullTypeResolution(sema.typeOf(slice)); |
| 23930 | return block.addBinOp(.slice_elem_val, slice, elem_index); | 23951 | return block.addBinOp(.slice_elem_val, slice, elem_index); |
| ... | @@ -23983,7 +24004,7 @@ fn elemPtrSlice( | ... | @@ -23983,7 +24004,7 @@ fn elemPtrSlice( |
| 23983 | break :len try block.addTyOp(.slice_len, Type.usize, slice); | 24004 | break :len try block.addTyOp(.slice_len, Type.usize, slice); |
| 23984 | }; | 24005 | }; |
| 23985 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 24006 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 23986 | try sema.panicIndexOutOfBounds(block, elem_index_src, elem_index, len_inst, cmp_op); | 24007 | try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op); |
| 23987 | } | 24008 | } |
| 23988 | return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty); | 24009 | return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty); |
| 23989 | } | 24010 | } |
| ... | @@ -28028,7 +28049,11 @@ fn analyzeSlice( | ... | @@ -28028,7 +28049,11 @@ fn analyzeSlice( |
| 28028 | } | 28049 | } |
| 28029 | } | 28050 | } |
| 28030 | | 28051 | |
| 28031 | const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src); | 28052 | if (block.wantSafety() and !block.is_comptime) { |
| | 28053 | // requirement: start <= end |
| | 28054 | try sema.panicStartLargerThanEnd(block, start, end); |
| | 28055 | } |
| | 28056 | const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); |
| 28032 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); | 28057 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| 28033 | | 28058 | |
| 28034 | const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data; | 28059 | const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data; |
| ... | @@ -28063,18 +28088,18 @@ fn analyzeSlice( | ... | @@ -28063,18 +28088,18 @@ fn analyzeSlice( |
| 28063 | const actual_len = if (slice_ty.sentinel() == null) | 28088 | const actual_len = if (slice_ty.sentinel() == null) |
| 28064 | slice_len_inst | 28089 | slice_len_inst |
| 28065 | else | 28090 | else |
| 28066 | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); | 28091 | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| 28067 | | 28092 | |
| 28068 | const actual_end = if (slice_sentinel != null) | 28093 | const actual_end = if (slice_sentinel != null) |
| 28069 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) | 28094 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) |
| 28070 | else | 28095 | else |
| 28071 | end; | 28096 | end; |
| 28072 | | 28097 | |
| 28073 | try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte); | 28098 | try sema.panicIndexOutOfBounds(block, actual_end, actual_len, .cmp_lte); |
| 28074 | } | 28099 | } |
| 28075 | | 28100 | |
| 28076 | // requirement: result[new_len] == slice_sentinel | 28101 | // requirement: result[new_len] == slice_sentinel |
| 28077 | try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len); | 28102 | try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len); |
| 28078 | } | 28103 | } |
| 28079 | return result; | 28104 | return result; |
| 28080 | }; | 28105 | }; |
| ... | @@ -28131,18 +28156,18 @@ fn analyzeSlice( | ... | @@ -28131,18 +28156,18 @@ fn analyzeSlice( |
| 28131 | if (slice_ty.sentinel() == null) break :blk slice_len_inst; | 28156 | if (slice_ty.sentinel() == null) break :blk slice_len_inst; |
| 28132 | | 28157 | |
| 28133 | // we have to add one because slice lengths don't include the sentinel | 28158 | // 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); | 28159 | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| 28135 | } else null; | 28160 | } else null; |
| 28136 | if (opt_len_inst) |len_inst| { | 28161 | if (opt_len_inst) |len_inst| { |
| 28137 | const actual_end = if (slice_sentinel != null) | 28162 | const actual_end = if (slice_sentinel != null) |
| 28138 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) | 28163 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) |
| 28139 | else | 28164 | else |
| 28140 | end; | 28165 | end; |
| 28141 | try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte); | 28166 | try sema.panicIndexOutOfBounds(block, actual_end, len_inst, .cmp_lte); |
| 28142 | } | 28167 | } |
| 28143 | | 28168 | |
| 28144 | // requirement: start <= end | 28169 | // requirement: start <= end |
| 28145 | try sema.panicIndexOutOfBounds(block, src, start, end, .cmp_lte); | 28170 | try sema.panicIndexOutOfBounds(block, start, end, .cmp_lte); |
| 28146 | } | 28171 | } |
| 28147 | const result = try block.addInst(.{ | 28172 | const result = try block.addInst(.{ |
| 28148 | .tag = .slice, | 28173 | .tag = .slice, |
| ... | @@ -28156,7 +28181,7 @@ fn analyzeSlice( | ... | @@ -28156,7 +28181,7 @@ fn analyzeSlice( |
| 28156 | }); | 28181 | }); |
| 28157 | if (block.wantSafety()) { | 28182 | if (block.wantSafety()) { |
| 28158 | // requirement: result[new_len] == slice_sentinel | 28183 | // requirement: result[new_len] == slice_sentinel |
| 28159 | try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len); | 28184 | try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len); |
| 28160 | } | 28185 | } |
| 28161 | return result; | 28186 | return result; |
| 28162 | } | 28187 | } |