authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-02 15:17:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-02 16:12:30-07:00
log89d660c3ebed27996ac08c9cb3d75718d6a007db
treec7bd0af065fbb5b1f1de62415653602ea623c100
parent9e19969e09ffee8aca39f28a42d566cc62b479d6

Sema: improve new error messages related to naked functions

* pass a source location to all safety checks * add notes about what is disallowed in naked functions Closes #16651

4 files changed, 219 insertions(+), 106 deletions(-)

src/Sema.zig+151-106
...@@ -745,9 +745,9 @@ pub const Block = struct {...@@ -745,9 +745,9 @@ pub const Block = struct {
745 return result_index;745 return result_index;
746 }746 }
747747
748 fn addUnreachable(block: *Block, safety_check: bool) !void {748 fn addUnreachable(block: *Block, src: LazySrcLoc, safety_check: bool) !void {
749 if (safety_check and block.wantSafety()) {749 if (safety_check and block.wantSafety()) {
750 try block.sema.safetyPanic(block, .unreach);750 try block.sema.safetyPanic(block, src, .unreach);
751 } else {751 } else {
752 _ = try block.addNoOp(.unreach);752 _ = try block.addNoOp(.unreach);
753 }753 }
...@@ -4304,7 +4304,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4304,7 +4304,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4304 if (arg_len == .none) continue;4304 if (arg_len == .none) continue;
4305 if (i == len_idx) continue;4305 if (i == len_idx) continue;
4306 const ok = try block.addBinOp(.cmp_eq, len, arg_len);4306 const ok = try block.addBinOp(.cmp_eq, len, arg_len);
4307 try sema.addSafetyCheck(block, ok, .for_len_mismatch);4307 try sema.addSafetyCheck(block, src, ok, .for_len_mismatch);
4308 }4308 }
4309 }4309 }
43104310
...@@ -5442,7 +5442,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I...@@ -5442,7 +5442,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I
5442 if (block.is_comptime) {5442 if (block.is_comptime) {
5443 return sema.fail(block, src, "encountered @panic at comptime", .{});5443 return sema.fail(block, src, "encountered @panic at comptime", .{});
5444 }5444 }
5445 try sema.panicWithMsg(block, msg_inst);5445 try sema.panicWithMsg(block, src, msg_inst, .@"@panic");
5446 return always_noreturn;5446 return always_noreturn;
5447}5447}
54485448
...@@ -6605,7 +6605,7 @@ fn zirCall(...@@ -6605,7 +6605,7 @@ fn zirCall(
6605 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))6605 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))
6606 {6606 {
6607 const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: {6607 const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: {
6608 break :b try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);6608 break :b try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node, .call);
6609 };6609 };
66106610
6611 const return_ty = sema.typeOf(call_inst);6611 const return_ty = sema.typeOf(call_inst);
...@@ -6635,11 +6635,11 @@ fn zirCall(...@@ -6635,11 +6635,11 @@ fn zirCall(
6635 }6635 }
66366636
6637 if (modifier == .always_tail) // Perform the call *after* the restore, so that a tail call is possible.6637 if (modifier == .always_tail) // Perform the call *after* the restore, so that a tail call is possible.
6638 return sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);6638 return sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node, .call);
66396639
6640 return call_inst;6640 return call_inst;
6641 } else {6641 } else {
6642 return sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);6642 return sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node, .call);
6643 }6643 }
6644}6644}
66456645
...@@ -6719,9 +6719,11 @@ fn checkCallArgumentCount(...@@ -6719,9 +6719,11 @@ fn checkCallArgumentCount(
6719fn callBuiltin(6719fn callBuiltin(
6720 sema: *Sema,6720 sema: *Sema,
6721 block: *Block,6721 block: *Block,
6722 call_src: LazySrcLoc,
6722 builtin_fn: Air.Inst.Ref,6723 builtin_fn: Air.Inst.Ref,
6723 modifier: std.builtin.CallModifier,6724 modifier: std.builtin.CallModifier,
6724 args: []const Air.Inst.Ref,6725 args: []const Air.Inst.Ref,
6726 operation: CallOperation,
6725) !void {6727) !void {
6726 const mod = sema.mod;6728 const mod = sema.mod;
6727 const callee_ty = sema.typeOf(builtin_fn);6729 const callee_ty = sema.typeOf(builtin_fn);
...@@ -6744,9 +6746,17 @@ fn callBuiltin(...@@ -6744,9 +6746,17 @@ fn callBuiltin(
6744 if (args.len != fn_params_len or (func_ty_info.is_var_args and args.len < fn_params_len)) {6746 if (args.len != fn_params_len or (func_ty_info.is_var_args and args.len < fn_params_len)) {
6745 std.debug.panic("parameter count mismatch calling builtin fn, expected {d}, found {d}", .{ fn_params_len, args.len });6747 std.debug.panic("parameter count mismatch calling builtin fn, expected {d}, found {d}", .{ fn_params_len, args.len });
6746 }6748 }
6747 _ = try sema.analyzeCall(block, builtin_fn, func_ty, sema.src, sema.src, modifier, false, args, null, null);6749 _ = try sema.analyzeCall(block, builtin_fn, func_ty, call_src, call_src, modifier, false, args, null, null, operation);
6748}6750}
67496751
6752const CallOperation = enum {
6753 call,
6754 @"@call",
6755 @"@panic",
6756 @"safety check",
6757 @"error return",
6758};
6759
6750fn analyzeCall(6760fn analyzeCall(
6751 sema: *Sema,6761 sema: *Sema,
6752 block: *Block,6762 block: *Block,
...@@ -6759,6 +6769,7 @@ fn analyzeCall(...@@ -6759,6 +6769,7 @@ fn analyzeCall(
6759 uncasted_args: []const Air.Inst.Ref,6769 uncasted_args: []const Air.Inst.Ref,
6760 bound_arg_src: ?LazySrcLoc,6770 bound_arg_src: ?LazySrcLoc,
6761 call_dbg_node: ?Zir.Inst.Index,6771 call_dbg_node: ?Zir.Inst.Index,
6772 operation: CallOperation,
6762) CompileError!Air.Inst.Ref {6773) CompileError!Air.Inst.Ref {
6763 const mod = sema.mod;6774 const mod = sema.mod;
6764 const ip = &mod.intern_pool;6775 const ip = &mod.intern_pool;
...@@ -6830,7 +6841,17 @@ fn analyzeCall(...@@ -6830,7 +6841,17 @@ fn analyzeCall(
6830 func_ty_info.cc == .Inline;6841 func_ty_info.cc == .Inline;
68316842
6832 if (sema.func_is_naked and !is_inline_call and !is_comptime_call) {6843 if (sema.func_is_naked and !is_inline_call and !is_comptime_call) {
6833 return sema.fail(block, call_src, "runtime call not allowed in naked function", .{});6844 const msg = msg: {
6845 const msg = try sema.errMsg(block, call_src, "runtime {s} not allowed in naked function", .{@tagName(operation)});
6846 errdefer msg.destroy(sema.gpa);
6847
6848 switch (operation) {
6849 .call, .@"@call", .@"@panic", .@"error return" => {},
6850 .@"safety check" => try sema.errNote(block, call_src, msg, "use @setRuntimeSafety to disable runtime safety", .{}),
6851 }
6852 break :msg msg;
6853 };
6854 return sema.failWithOwnedErrorMsg(msg);
6834 }6855 }
68356856
6836 if (!is_inline_call and is_generic_call) {6857 if (!is_inline_call and is_generic_call) {
...@@ -7281,7 +7302,7 @@ fn analyzeCall(...@@ -7281,7 +7302,7 @@ fn analyzeCall(
7281 else => {},7302 else => {},
7282 }7303 }
7283 }7304 }
7284 try sema.safetyPanic(block, .noreturn_returned);7305 try sema.safetyPanic(block, call_src, .noreturn_returned);
7285 return Air.Inst.Ref.unreachable_value;7306 return Air.Inst.Ref.unreachable_value;
7286 }7307 }
7287 if (func_ty_info.return_type == .noreturn_type) {7308 if (func_ty_info.return_type == .noreturn_type) {
...@@ -7939,7 +7960,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -7939,7 +7960,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
7939 const zero_val = try sema.addConstant(try mod.intValue(Type.err_int, 0));7960 const zero_val = try sema.addConstant(try mod.intValue(Type.err_int, 0));
7940 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);7961 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
7941 const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero);7962 const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero);
7942 try sema.addSafetyCheck(block, ok, .invalid_error_code);7963 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
7943 }7964 }
7944 return block.addInst(.{7965 return block.addInst(.{
7945 .tag = .bitcast,7966 .tag = .bitcast,
...@@ -8131,7 +8152,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8131,7 +8152,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8131 mod.backendSupportsFeature(.is_named_enum_value))8152 mod.backendSupportsFeature(.is_named_enum_value))
8132 {8153 {
8133 const ok = try block.addUnOp(.is_named_enum_value, result);8154 const ok = try block.addUnOp(.is_named_enum_value, result);
8134 try sema.addSafetyCheck(block, ok, .invalid_enum_value);8155 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
8135 }8156 }
8136 return result;8157 return result;
8137}8158}
...@@ -8207,7 +8228,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8207,7 +8228,7 @@ fn analyzeOptionalPayloadPtr(
8207 try sema.requireRuntimeBlock(block, src, null);8228 try sema.requireRuntimeBlock(block, src, null);
8208 if (safety_check and block.wantSafety()) {8229 if (safety_check and block.wantSafety()) {
8209 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);8230 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);
8210 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);8231 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
8211 }8232 }
8212 const air_tag: Air.Inst.Tag = if (initializing)8233 const air_tag: Air.Inst.Tag = if (initializing)
8213 .optional_payload_ptr_set8234 .optional_payload_ptr_set
...@@ -8264,7 +8285,7 @@ fn zirOptionalPayload(...@@ -8264,7 +8285,7 @@ fn zirOptionalPayload(
8264 try sema.requireRuntimeBlock(block, src, null);8285 try sema.requireRuntimeBlock(block, src, null);
8265 if (safety_check and block.wantSafety()) {8286 if (safety_check and block.wantSafety()) {
8266 const is_non_null = try block.addUnOp(.is_non_null, operand);8287 const is_non_null = try block.addUnOp(.is_non_null, operand);
8267 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);8288 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
8268 }8289 }
8269 return block.addTyOp(.optional_payload, result_ty, operand);8290 return block.addTyOp(.optional_payload, result_ty, operand);
8270}8291}
...@@ -8318,7 +8339,7 @@ fn analyzeErrUnionPayload(...@@ -8318,7 +8339,7 @@ fn analyzeErrUnionPayload(
8318 if (safety_check and block.wantSafety() and8339 if (safety_check and block.wantSafety() and
8319 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))8340 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
8320 {8341 {
8321 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err);8342 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);
8322 }8343 }
83238344
8324 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);8345 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);
...@@ -8399,7 +8420,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -8399,7 +8420,7 @@ fn analyzeErrUnionPayloadPtr(
8399 if (safety_check and block.wantSafety() and8420 if (safety_check and block.wantSafety() and
8400 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))8421 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
8401 {8422 {
8402 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);8423 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
8403 }8424 }
84048425
8405 const air_tag: Air.Inst.Tag = if (initializing)8426 const air_tag: Air.Inst.Tag = if (initializing)
...@@ -9637,7 +9658,7 @@ fn intCast(...@@ -9637,7 +9658,7 @@ fn intCast(
9637 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);9658 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
9638 break :ok is_in_range;9659 break :ok is_in_range;
9639 };9660 };
9640 try sema.addSafetyCheck(block, ok, .cast_truncated_data);9661 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
9641 }9662 }
9642 }9663 }
96439664
...@@ -9691,7 +9712,7 @@ fn intCast(...@@ -9691,7 +9712,7 @@ fn intCast(
9691 break :ok is_in_range;9712 break :ok is_in_range;
9692 };9713 };
9693 // TODO negative_to_unsigned?9714 // TODO negative_to_unsigned?
9694 try sema.addSafetyCheck(block, ok, .cast_truncated_data);9715 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
9695 } else {9716 } else {
9696 const ok = if (is_vector) ok: {9717 const ok = if (is_vector) ok: {
9697 const is_in_range = try block.addCmpVector(diff, dest_max, .lte);9718 const is_in_range = try block.addCmpVector(diff, dest_max, .lte);
...@@ -9707,7 +9728,7 @@ fn intCast(...@@ -9707,7 +9728,7 @@ fn intCast(
9707 const is_in_range = try block.addBinOp(.cmp_lte, diff, dest_max);9728 const is_in_range = try block.addBinOp(.cmp_lte, diff, dest_max);
9708 break :ok is_in_range;9729 break :ok is_in_range;
9709 };9730 };
9710 try sema.addSafetyCheck(block, ok, .cast_truncated_data);9731 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
9711 }9732 }
9712 } else if (actual_info.signedness == .signed and wanted_info.signedness == .unsigned) {9733 } else if (actual_info.signedness == .signed and wanted_info.signedness == .unsigned) {
9713 // no shrinkage, yes sign loss9734 // no shrinkage, yes sign loss
...@@ -9730,7 +9751,7 @@ fn intCast(...@@ -9730,7 +9751,7 @@ fn intCast(
9730 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);9751 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);
9731 break :ok is_in_range;9752 break :ok is_in_range;
9732 };9753 };
9733 try sema.addSafetyCheck(block, ok, .negative_to_unsigned);9754 try sema.addSafetyCheck(block, src, ok, .negative_to_unsigned);
9734 }9755 }
9735 }9756 }
9736 return block.addTyOp(.intcast, dest_ty, operand);9757 return block.addTyOp(.intcast, dest_ty, operand);
...@@ -10319,7 +10340,7 @@ const SwitchProngAnalysis = struct {...@@ -10319,7 +10340,7 @@ const SwitchProngAnalysis = struct {
10319 .ErrorSet => if (spa.else_error_ty) |ty| {10340 .ErrorSet => if (spa.else_error_ty) |ty| {
10320 return sema.bitCast(block, ty, spa.operand, operand_src, null);10341 return sema.bitCast(block, ty, spa.operand, operand_src, null);
10321 } else {10342 } else {
10322 try block.addUnreachable(false);10343 try block.addUnreachable(operand_src, false);
10323 return Air.Inst.Ref.unreachable_value;10344 return Air.Inst.Ref.unreachable_value;
10324 },10345 },
10325 else => return spa.operand,10346 else => return spa.operand,
...@@ -11475,7 +11496,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11475,7 +11496,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11475 if (special_prong == .none) {11496 if (special_prong == .none) {
11476 return sema.fail(block, src, "switch must handle all possibilities", .{});11497 return sema.fail(block, src, "switch must handle all possibilities", .{});
11477 }11498 }
11478 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {11499 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand, operand_src)) {
11479 return Air.Inst.Ref.unreachable_value;11500 return Air.Inst.Ref.unreachable_value;
11480 }11501 }
11481 if (mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and11502 if (mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and
...@@ -11483,7 +11504,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11483,7 +11504,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11483 {11504 {
11484 try sema.zirDbgStmt(block, cond_dbg_node_index);11505 try sema.zirDbgStmt(block, cond_dbg_node_index);
11485 const ok = try block.addUnOp(.is_named_enum_value, operand);11506 const ok = try block.addUnOp(.is_named_enum_value, operand);
11486 try sema.addSafetyCheck(block, ok, .corrupt_switch);11507 try sema.addSafetyCheck(block, src, ok, .corrupt_switch);
11487 }11508 }
1148811509
11489 return spa.resolveProngComptime(11510 return spa.resolveProngComptime(
...@@ -11543,7 +11564,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11543,7 +11564,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11543 break :blk field_ty.zigTypeTag(mod) != .NoReturn;11564 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
11544 } else true;11565 } else true;
1154511566
11546 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) {11567 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand, operand_src)) {
11547 // nothing to do here11568 // nothing to do here
11548 } else if (analyze_body) {11569 } else if (analyze_body) {
11549 try spa.analyzeProngRuntime(11570 try spa.analyzeProngRuntime(
...@@ -11725,7 +11746,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11725,7 +11746,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1172511746
11726 const body = sema.code.extra[extra_index..][0..info.body_len];11747 const body = sema.code.extra[extra_index..][0..info.body_len];
11727 extra_index += info.body_len;11748 extra_index += info.body_len;
11728 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) {11749 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand, operand_src)) {
11729 // nothing to do here11750 // nothing to do here
11730 } else if (analyze_body) {11751 } else if (analyze_body) {
11731 try spa.analyzeProngRuntime(11752 try spa.analyzeProngRuntime(
...@@ -11812,7 +11833,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11812,7 +11833,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1181211833
11813 const body = sema.code.extra[extra_index..][0..info.body_len];11834 const body = sema.code.extra[extra_index..][0..info.body_len];
11814 extra_index += info.body_len;11835 extra_index += info.body_len;
11815 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) {11836 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand, operand_src)) {
11816 // nothing to do here11837 // nothing to do here
11817 } else {11838 } else {
11818 try spa.analyzeProngRuntime(11839 try spa.analyzeProngRuntime(
...@@ -12045,7 +12066,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12045,7 +12066,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12045 {12066 {
12046 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);12067 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
12047 const ok = try case_block.addUnOp(.is_named_enum_value, operand);12068 const ok = try case_block.addUnOp(.is_named_enum_value, operand);
12048 try sema.addSafetyCheck(&case_block, ok, .corrupt_switch);12069 try sema.addSafetyCheck(&case_block, src, ok, .corrupt_switch);
12049 }12070 }
1205012071
12051 const analyze_body = if (union_originally and !special.is_inline)12072 const analyze_body = if (union_originally and !special.is_inline)
...@@ -12058,7 +12079,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12058,7 +12079,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12058 else12079 else
12059 true;12080 true;
12060 if (special.body.len != 0 and err_set and12081 if (special.body.len != 0 and err_set and
12061 try sema.maybeErrorUnwrap(&case_block, special.body, operand))12082 try sema.maybeErrorUnwrap(&case_block, special.body, operand, operand_src))
12062 {12083 {
12063 // nothing to do here12084 // nothing to do here
12064 } else if (special.body.len != 0 and analyze_body and !special.is_inline) {12085 } else if (special.body.len != 0 and analyze_body and !special.is_inline) {
...@@ -12077,7 +12098,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12077,7 +12098,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12077 // that it is unreachable.12098 // that it is unreachable.
12078 if (case_block.wantSafety()) {12099 if (case_block.wantSafety()) {
12079 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);12100 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
12080 try sema.safetyPanic(&case_block, .corrupt_switch);12101 try sema.safetyPanic(&case_block, src, .corrupt_switch);
12081 } else {12102 } else {
12082 _ = try case_block.addNoOp(.unreach);12103 _ = try case_block.addNoOp(.unreach);
12083 }12104 }
...@@ -12420,7 +12441,7 @@ fn validateSwitchNoRange(...@@ -12420,7 +12441,7 @@ fn validateSwitchNoRange(
12420 return sema.failWithOwnedErrorMsg(msg);12441 return sema.failWithOwnedErrorMsg(msg);
12421}12442}
1242212443
12423fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool {12444fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref, operand_src: LazySrcLoc) !bool {
12424 const mod = sema.mod;12445 const mod = sema.mod;
12425 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;12446 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;
1242612447
...@@ -12459,14 +12480,14 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -12459,14 +12480,14 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
12459 .field_val => try sema.zirFieldVal(block, inst),12480 .field_val => try sema.zirFieldVal(block, inst),
12460 .@"unreachable" => {12481 .@"unreachable" => {
12461 if (!mod.comp.formatted_panics) {12482 if (!mod.comp.formatted_panics) {
12462 try sema.safetyPanic(block, .unwrap_error);12483 try sema.safetyPanic(block, operand_src, .unwrap_error);
12463 return true;12484 return true;
12464 }12485 }
1246512486
12466 const panic_fn = try sema.getBuiltin("panicUnwrapError");12487 const panic_fn = try sema.getBuiltin("panicUnwrapError");
12467 const err_return_trace = try sema.getErrorReturnTrace(block);12488 const err_return_trace = try sema.getErrorReturnTrace(block);
12468 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };12489 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
12469 try sema.callBuiltin(block, panic_fn, .auto, &args);12490 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
12470 return true;12491 return true;
12471 },12492 },
12472 .panic => {12493 .panic => {
...@@ -12476,7 +12497,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -12476,7 +12497,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
12476 const panic_fn = try sema.getBuiltin("panic");12497 const panic_fn = try sema.getBuiltin("panic");
12477 const err_return_trace = try sema.getErrorReturnTrace(block);12498 const err_return_trace = try sema.getErrorReturnTrace(block);
12478 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };12499 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
12479 try sema.callBuiltin(block, panic_fn, .auto, &args);12500 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
12480 return true;12501 return true;
12481 },12502 },
12482 else => unreachable,12503 else => unreachable,
...@@ -12851,7 +12872,7 @@ fn zirShl(...@@ -12851,7 +12872,7 @@ fn zirShl(
12851 const bit_count_inst = try sema.addConstant(bit_count_val);12872 const bit_count_inst = try sema.addConstant(bit_count_val);
12852 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);12873 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
12853 };12874 };
12854 try sema.addSafetyCheck(block, ok, .shift_rhs_too_big);12875 try sema.addSafetyCheck(block, src, ok, .shift_rhs_too_big);
12855 }12876 }
1285612877
12857 if (air_tag == .shl_exact) {12878 if (air_tag == .shl_exact) {
...@@ -12880,7 +12901,7 @@ fn zirShl(...@@ -12880,7 +12901,7 @@ fn zirShl(
12880 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));12901 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));
12881 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);12902 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1288212903
12883 try sema.addSafetyCheck(block, no_ov, .shl_overflow);12904 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);
12884 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);12905 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);
12885 }12906 }
12886 }12907 }
...@@ -13001,7 +13022,7 @@ fn zirShr(...@@ -13001,7 +13022,7 @@ fn zirShr(
13001 const bit_count_inst = try sema.addConstant(bit_count_val);13022 const bit_count_inst = try sema.addConstant(bit_count_val);
13002 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);13023 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
13003 };13024 };
13004 try sema.addSafetyCheck(block, ok, .shift_rhs_too_big);13025 try sema.addSafetyCheck(block, src, ok, .shift_rhs_too_big);
13005 }13026 }
1300613027
13007 if (air_tag == .shr_exact) {13028 if (air_tag == .shr_exact) {
...@@ -13017,7 +13038,7 @@ fn zirShr(...@@ -13017,7 +13038,7 @@ fn zirShr(
13017 } },13038 } },
13018 });13039 });
13019 } else try block.addBinOp(.cmp_eq, lhs, back);13040 } else try block.addBinOp(.cmp_eq, lhs, back);
13020 try sema.addSafetyCheck(block, ok, .shr_overflow);13041 try sema.addSafetyCheck(block, src, ok, .shr_overflow);
13021 }13042 }
13022 }13043 }
13023 return result;13044 return result;
...@@ -13894,8 +13915,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13894,8 +13915,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13894 try sema.requireRuntimeBlock(block, src, runtime_src);13915 try sema.requireRuntimeBlock(block, src, runtime_src);
1389513916
13896 if (block.wantSafety()) {13917 if (block.wantSafety()) {
13897 try sema.addDivIntOverflowSafety(block, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);13918 try sema.addDivIntOverflowSafety(block, src, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);
13898 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);13919 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
13899 }13920 }
1390013921
13901 const air_tag = if (is_int) blk: {13922 const air_tag = if (is_int) blk: {
...@@ -14025,8 +14046,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14025,8 +14046,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14025 // div_trunc and check for remainder.14046 // div_trunc and check for remainder.
1402614047
14027 if (block.wantSafety()) {14048 if (block.wantSafety()) {
14028 try sema.addDivIntOverflowSafety(block, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);14049 try sema.addDivIntOverflowSafety(block, src, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);
14029 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14050 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
1403014051
14031 const result = try block.addBinOp(.div_trunc, casted_lhs, casted_rhs);14052 const result = try block.addBinOp(.div_trunc, casted_lhs, casted_rhs);
14032 const ok = if (!is_int) ok: {14053 const ok = if (!is_int) ok: {
...@@ -14076,7 +14097,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14076,7 +14097,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14076 break :ok is_in_range;14097 break :ok is_in_range;
14077 }14098 }
14078 };14099 };
14079 try sema.addSafetyCheck(block, ok, .exact_division_remainder);14100 try sema.addSafetyCheck(block, src, ok, .exact_division_remainder);
14080 return result;14101 return result;
14081 }14102 }
1408214103
...@@ -14191,8 +14212,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14191,8 +14212,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14191 try sema.requireRuntimeBlock(block, src, runtime_src);14212 try sema.requireRuntimeBlock(block, src, runtime_src);
1419214213
14193 if (block.wantSafety()) {14214 if (block.wantSafety()) {
14194 try sema.addDivIntOverflowSafety(block, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);14215 try sema.addDivIntOverflowSafety(block, src, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);
14195 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14216 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
14196 }14217 }
1419714218
14198 return block.addBinOp(airTag(block, is_int, .div_floor, .div_floor_optimized), casted_lhs, casted_rhs);14219 return block.addBinOp(airTag(block, is_int, .div_floor, .div_floor_optimized), casted_lhs, casted_rhs);
...@@ -14308,8 +14329,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14308,8 +14329,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14308 try sema.requireRuntimeBlock(block, src, runtime_src);14329 try sema.requireRuntimeBlock(block, src, runtime_src);
1430914330
14310 if (block.wantSafety()) {14331 if (block.wantSafety()) {
14311 try sema.addDivIntOverflowSafety(block, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);14332 try sema.addDivIntOverflowSafety(block, src, resolved_type, lhs_scalar_ty, maybe_lhs_val, maybe_rhs_val, casted_lhs, casted_rhs, is_int);
14312 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14333 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
14313 }14334 }
1431414335
14315 return block.addBinOp(airTag(block, is_int, .div_trunc, .div_trunc_optimized), casted_lhs, casted_rhs);14336 return block.addBinOp(airTag(block, is_int, .div_trunc, .div_trunc_optimized), casted_lhs, casted_rhs);
...@@ -14318,6 +14339,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14318,6 +14339,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14318fn addDivIntOverflowSafety(14339fn addDivIntOverflowSafety(
14319 sema: *Sema,14340 sema: *Sema,
14320 block: *Block,14341 block: *Block,
14342 src: LazySrcLoc,
14321 resolved_type: Type,14343 resolved_type: Type,
14322 lhs_scalar_ty: Type,14344 lhs_scalar_ty: Type,
14323 maybe_lhs_val: ?Value,14345 maybe_lhs_val: ?Value,
...@@ -14391,12 +14413,13 @@ fn addDivIntOverflowSafety(...@@ -14391,12 +14413,13 @@ fn addDivIntOverflowSafety(
14391 }14413 }
14392 assert(ok != .none);14414 assert(ok != .none);
14393 }14415 }
14394 try sema.addSafetyCheck(block, ok, .integer_overflow);14416 try sema.addSafetyCheck(block, src, ok, .integer_overflow);
14395}14417}
1439614418
14397fn addDivByZeroSafety(14419fn addDivByZeroSafety(
14398 sema: *Sema,14420 sema: *Sema,
14399 block: *Block,14421 block: *Block,
14422 src: LazySrcLoc,
14400 resolved_type: Type,14423 resolved_type: Type,
14401 maybe_rhs_val: ?Value,14424 maybe_rhs_val: ?Value,
14402 casted_rhs: Air.Inst.Ref,14425 casted_rhs: Air.Inst.Ref,
...@@ -14429,7 +14452,7 @@ fn addDivByZeroSafety(...@@ -14429,7 +14452,7 @@ fn addDivByZeroSafety(
14429 const zero = try sema.addConstant(scalar_zero);14452 const zero = try sema.addConstant(scalar_zero);
14430 break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);14453 break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);
14431 };14454 };
14432 try sema.addSafetyCheck(block, ok, .divide_by_zero);14455 try sema.addSafetyCheck(block, src, ok, .divide_by_zero);
14433}14456}
1443414457
14435fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst.Tag) Air.Inst.Tag {14458fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst.Tag) Air.Inst.Tag {
...@@ -14569,7 +14592,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14569,7 +14592,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14569 try sema.requireRuntimeBlock(block, src, runtime_src);14592 try sema.requireRuntimeBlock(block, src, runtime_src);
1457014593
14571 if (block.wantSafety()) {14594 if (block.wantSafety()) {
14572 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14595 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
14573 }14596 }
1457414597
14575 const air_tag = airTag(block, is_int, .rem, .rem_optimized);14598 const air_tag = airTag(block, is_int, .rem, .rem_optimized);
...@@ -14720,7 +14743,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14720,7 +14743,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14720 try sema.requireRuntimeBlock(block, src, runtime_src);14743 try sema.requireRuntimeBlock(block, src, runtime_src);
1472114744
14722 if (block.wantSafety()) {14745 if (block.wantSafety()) {
14723 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14746 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
14724 }14747 }
1472514748
14726 const air_tag = airTag(block, is_int, .mod, .mod_optimized);14749 const air_tag = airTag(block, is_int, .mod, .mod_optimized);
...@@ -14820,7 +14843,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -14820,7 +14843,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
14820 try sema.requireRuntimeBlock(block, src, runtime_src);14843 try sema.requireRuntimeBlock(block, src, runtime_src);
1482114844
14822 if (block.wantSafety()) {14845 if (block.wantSafety()) {
14823 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, casted_rhs, is_int);14846 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
14824 }14847 }
1482514848
14826 const air_tag = airTag(block, is_int, .rem, .rem_optimized);14849 const air_tag = airTag(block, is_int, .rem, .rem_optimized);
...@@ -15558,7 +15581,7 @@ fn analyzeArithmetic(...@@ -15558,7 +15581,7 @@ fn analyzeArithmetic(
15558 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));15581 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));
15559 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);15582 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1556015583
15561 try sema.addSafetyCheck(block, no_ov, .integer_overflow);15584 try sema.addSafetyCheck(block, src, no_ov, .integer_overflow);
15562 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);15585 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);
15563 }15586 }
15564 }15587 }
...@@ -17979,7 +18002,7 @@ fn zirCondbr(...@@ -17979,7 +18002,7 @@ fn zirCondbr(
17979 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);18002 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
17980 };18003 };
1798118004
17982 if (err_cond != null and try sema.maybeErrorUnwrap(&sub_block, else_body, err_cond.?)) {18005 if (err_cond != null and try sema.maybeErrorUnwrap(&sub_block, else_body, err_cond.?, cond_src)) {
17983 // nothing to do18006 // nothing to do
17984 } else {18007 } else {
17985 try sema.analyzeBodyRuntimeBreak(&sub_block, else_body);18008 try sema.analyzeBodyRuntimeBreak(&sub_block, else_body);
...@@ -18171,7 +18194,15 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -18171,7 +18194,15 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
18171 return sema.fail(block, src, "reached unreachable code", .{});18194 return sema.fail(block, src, "reached unreachable code", .{});
18172 }18195 }
18173 // TODO Add compile error for @optimizeFor occurring too late in a scope.18196 // TODO Add compile error for @optimizeFor occurring too late in a scope.
18174 try block.addUnreachable(true);18197 block.addUnreachable(src, true) catch |err| switch (err) {
18198 error.AnalysisFail => {
18199 const msg = sema.err orelse return err;
18200 if (!mem.eql(u8, msg.msg, "runtime safety check not allowed in naked function")) return err;
18201 try sema.errNote(block, src, msg, "the end of a naked function is implicitly unreachable", .{});
18202 return err;
18203 },
18204 else => |e| return e,
18205 };
18175 return always_noreturn;18206 return always_noreturn;
18176}18207}
1817718208
...@@ -18202,21 +18233,21 @@ fn zirRetImplicit(...@@ -18202,21 +18233,21 @@ fn zirRetImplicit(
18202 const tracy = trace(@src());18233 const tracy = trace(@src());
18203 defer tracy.end();18234 defer tracy.end();
1820418235
18236 const mod = sema.mod;
18237 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
18238 const r_brace_src = inst_data.src();
18205 if (block.inlining == null and sema.func_is_naked) {18239 if (block.inlining == null and sema.func_is_naked) {
18206 assert(!block.is_comptime);18240 assert(!block.is_comptime);
18207 if (block.wantSafety()) {18241 if (block.wantSafety()) {
18208 // Calling a safety function from a naked function would not be legal.18242 // Calling a safety function from a naked function would not be legal.
18209 _ = try block.addNoOp(.trap);18243 _ = try block.addNoOp(.trap);
18210 } else {18244 } else {
18211 try block.addUnreachable(false);18245 try block.addUnreachable(r_brace_src, false);
18212 }18246 }
18213 return always_noreturn;18247 return always_noreturn;
18214 }18248 }
1821518249
18216 const mod = sema.mod;
18217 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
18218 const operand = try sema.resolveInst(inst_data.operand);18250 const operand = try sema.resolveInst(inst_data.operand);
18219 const r_brace_src = inst_data.src();
18220 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };18251 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
18221 const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod);18252 const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod);
18222 if (base_tag == .NoReturn) {18253 if (base_tag == .NoReturn) {
...@@ -18270,7 +18301,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -18270,7 +18301,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1827018301
18271 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {18302 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
18272 const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr);18303 const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr);
18273 return sema.retWithErrTracing(block, is_non_err, .ret_load, ret_ptr);18304 return sema.retWithErrTracing(block, src, is_non_err, .ret_load, ret_ptr);
18274 }18305 }
1827518306
18276 _ = try block.addUnOp(.ret_load, ret_ptr);18307 _ = try block.addUnOp(.ret_load, ret_ptr);
...@@ -18280,6 +18311,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -18280,6 +18311,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
18280fn retWithErrTracing(18311fn retWithErrTracing(
18281 sema: *Sema,18312 sema: *Sema,
18282 block: *Block,18313 block: *Block,
18314 src: LazySrcLoc,
18283 is_non_err: Air.Inst.Ref,18315 is_non_err: Air.Inst.Ref,
18284 ret_tag: Air.Inst.Tag,18316 ret_tag: Air.Inst.Tag,
18285 operand: Air.Inst.Ref,18317 operand: Air.Inst.Ref,
...@@ -18302,7 +18334,7 @@ fn retWithErrTracing(...@@ -18302,7 +18334,7 @@ fn retWithErrTracing(
18302 const args: [1]Air.Inst.Ref = .{err_return_trace};18334 const args: [1]Air.Inst.Ref = .{err_return_trace};
1830318335
18304 if (!need_check) {18336 if (!need_check) {
18305 try sema.callBuiltin(block, return_err_fn, .never_inline, &args);18337 try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return");
18306 _ = try block.addUnOp(ret_tag, operand);18338 _ = try block.addUnOp(ret_tag, operand);
18307 return always_noreturn;18339 return always_noreturn;
18308 }18340 }
...@@ -18313,7 +18345,7 @@ fn retWithErrTracing(...@@ -18313,7 +18345,7 @@ fn retWithErrTracing(
1831318345
18314 var else_block = block.makeSubBlock();18346 var else_block = block.makeSubBlock();
18315 defer else_block.instructions.deinit(gpa);18347 defer else_block.instructions.deinit(gpa);
18316 try sema.callBuiltin(&else_block, return_err_fn, .never_inline, &args);18348 try sema.callBuiltin(&else_block, src, return_err_fn, .never_inline, &args, .@"error return");
18317 _ = try else_block.addUnOp(ret_tag, operand);18349 _ = try else_block.addUnOp(ret_tag, operand);
1831818350
18319 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +18351 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
...@@ -18470,7 +18502,14 @@ fn analyzeRet(...@@ -18470,7 +18502,14 @@ fn analyzeRet(
18470 } else if (block.is_comptime) {18502 } else if (block.is_comptime) {
18471 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});18503 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});
18472 } else if (sema.func_is_naked) {18504 } else if (sema.func_is_naked) {
18473 return sema.fail(block, src, "cannot return from naked function", .{});18505 const msg = msg: {
18506 const msg = try sema.errMsg(block, src, "cannot return from naked function", .{});
18507 errdefer msg.destroy(sema.gpa);
18508
18509 try sema.errNote(block, src, msg, "can only return using assembly", .{});
18510 break :msg msg;
18511 };
18512 return sema.failWithOwnedErrorMsg(msg);
18474 }18513 }
1847518514
18476 try sema.resolveTypeLayout(sema.fn_ret_ty);18515 try sema.resolveTypeLayout(sema.fn_ret_ty);
...@@ -18479,7 +18518,7 @@ fn analyzeRet(...@@ -18479,7 +18518,7 @@ fn analyzeRet(
18479 // Avoid adding a frame to the error return trace in case the value is comptime-known18518 // Avoid adding a frame to the error return trace in case the value is comptime-known
18480 // to be not an error.18519 // to be not an error.
18481 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);18520 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);
18482 return sema.retWithErrTracing(block, is_non_err, .ret, operand);18521 return sema.retWithErrTracing(block, src, is_non_err, .ret, operand);
18483 }18522 }
1848418523
18485 _ = try block.addUnOp(.ret, operand);18524 _ = try block.addUnOp(.ret, operand);
...@@ -19624,7 +19663,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19624,7 +19663,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19624 try sema.requireRuntimeBlock(block, src, operand_src);19663 try sema.requireRuntimeBlock(block, src, operand_src);
19625 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {19664 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {
19626 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);19665 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
19627 try sema.addSafetyCheck(block, ok, .invalid_enum_value);19666 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
19628 }19667 }
19629 // In case the value is runtime-known, we have an AIR instruction for this instead19668 // In case the value is runtime-known, we have an AIR instruction for this instead
19630 // of trying to lower it in Sema because an optimization pass may result in the operand19669 // of trying to lower it in Sema because an optimization pass may result in the operand
...@@ -20769,7 +20808,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -20769,7 +20808,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
20769 if (dest_ty.intInfo(mod).bits == 0) {20808 if (dest_ty.intInfo(mod).bits == 0) {
20770 if (block.wantSafety()) {20809 if (block.wantSafety()) {
20771 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(try mod.floatValue(operand_ty, 0.0)));20810 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(try mod.floatValue(operand_ty, 0.0)));
20772 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);20811 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
20773 }20812 }
20774 return sema.addConstant(try mod.intValue(dest_ty, 0));20813 return sema.addConstant(try mod.intValue(dest_ty, 0));
20775 }20814 }
...@@ -20780,7 +20819,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -20780,7 +20819,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
20780 const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(try mod.floatValue(operand_ty, 1.0)));20819 const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(try mod.floatValue(operand_ty, 1.0)));
20781 const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(try mod.floatValue(operand_ty, -1.0)));20820 const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(try mod.floatValue(operand_ty, -1.0)));
20782 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);20821 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
20783 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);20822 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
20784 }20823 }
20785 return result;20824 return result;
20786}20825}
...@@ -20857,7 +20896,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20857,7 +20896,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20857 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {20896 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
20858 if (!ptr_ty.isAllowzeroPtr(mod)) {20897 if (!ptr_ty.isAllowzeroPtr(mod)) {
20859 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);20898 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
20860 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);20899 try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null);
20861 }20900 }
2086220901
20863 if (ptr_align > 1) {20902 if (ptr_align > 1) {
...@@ -20866,7 +20905,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20866,7 +20905,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20866 );20905 );
20867 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);20906 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
20868 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);20907 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
20869 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);20908 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
20870 }20909 }
20871 }20910 }
20872 return block.addBitCast(ptr_ty, operand_coerced);20911 return block.addBitCast(ptr_ty, operand_coerced);
...@@ -20954,7 +20993,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -20954,7 +20993,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
20954 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {20993 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
20955 const err_int_inst = try block.addBitCast(Type.err_int, operand);20994 const err_int_inst = try block.addBitCast(Type.err_int, operand);
20956 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);20995 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);
20957 try sema.addSafetyCheck(block, ok, .invalid_error_code);20996 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
20958 }20997 }
20959 return block.addBitCast(dest_ty, operand);20998 return block.addBitCast(dest_ty, operand);
20960}20999}
...@@ -21300,7 +21339,7 @@ fn ptrCastFull(...@@ -21300,7 +21339,7 @@ fn ptrCastFull(
21300 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);21339 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
21301 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);21340 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
21302 } else is_non_zero;21341 } else is_non_zero;
21303 try sema.addSafetyCheck(block, ok, .cast_to_null);21342 try sema.addSafetyCheck(block, src, ok, .cast_to_null);
21304 }21343 }
2130521344
21306 if (block.wantSafety() and dest_align > src_align and try sema.typeHasRuntimeBits(dest_info.child.toType())) {21345 if (block.wantSafety() and dest_align > src_align and try sema.typeHasRuntimeBits(dest_info.child.toType())) {
...@@ -21315,7 +21354,7 @@ fn ptrCastFull(...@@ -21315,7 +21354,7 @@ fn ptrCastFull(
21315 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);21354 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
21316 break :ok try block.addBinOp(.bit_or, len_zero, is_aligned);21355 break :ok try block.addBinOp(.bit_or, len_zero, is_aligned);
21317 } else is_aligned;21356 } else is_aligned;
21318 try sema.addSafetyCheck(block, ok, .incorrect_alignment);21357 try sema.addSafetyCheck(block, src, ok, .incorrect_alignment);
21319 }21358 }
2132021359
21321 // If we're going from an array pointer to a slice, this will only be the pointer part!21360 // If we're going from an array pointer to a slice, this will only be the pointer part!
...@@ -22992,7 +23031,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -22992,7 +23031,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
22992 const callee_ty = sema.typeOf(func);23031 const callee_ty = sema.typeOf(func);
22993 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);23032 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);
22994 const ensure_result_used = extra.flags.ensure_result_used;23033 const ensure_result_used = extra.flags.ensure_result_used;
22995 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null);23034 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null, .@"@call");
22996}23035}
2299723036
22998fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23037fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -23477,7 +23516,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -23477,7 +23516,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2347723516
23478 if (block.wantSafety()) {23517 if (block.wantSafety()) {
23479 const ok = try block.addBinOp(.cmp_eq, dest_len, src_len);23518 const ok = try block.addBinOp(.cmp_eq, dest_len, src_len);
23480 try sema.addSafetyCheck(block, ok, .memcpy_len_mismatch);23519 try sema.addSafetyCheck(block, src, ok, .memcpy_len_mismatch);
23481 }23520 }
23482 } else if (dest_len != .none) {23521 } else if (dest_len != .none) {
23483 if (try sema.resolveDefinedValue(block, dest_src, dest_len)) |dest_len_val| {23522 if (try sema.resolveDefinedValue(block, dest_src, dest_len)) |dest_len_val| {
...@@ -23619,7 +23658,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -23619,7 +23658,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
23619 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);23658 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);
23620 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);23659 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);
23621 const ok = try block.addBinOp(.bit_or, ok1, ok2);23660 const ok = try block.addBinOp(.bit_or, ok1, ok2);
23622 try sema.addSafetyCheck(block, ok, .memcpy_alias);23661 try sema.addSafetyCheck(block, src, ok, .memcpy_alias);
23623 }23662 }
2362423663
23625 _ = try block.addInst(.{23664 _ = try block.addInst(.{
...@@ -24862,6 +24901,7 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !Module....@@ -24862,6 +24901,7 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !Module.
24862fn addSafetyCheck(24901fn addSafetyCheck(
24863 sema: *Sema,24902 sema: *Sema,
24864 parent_block: *Block,24903 parent_block: *Block,
24904 src: LazySrcLoc,
24865 ok: Air.Inst.Ref,24905 ok: Air.Inst.Ref,
24866 panic_id: Module.PanicId,24906 panic_id: Module.PanicId,
24867) !void {24907) !void {
...@@ -24881,7 +24921,7 @@ fn addSafetyCheck(...@@ -24881,7 +24921,7 @@ fn addSafetyCheck(
2488124921
24882 defer fail_block.instructions.deinit(gpa);24922 defer fail_block.instructions.deinit(gpa);
2488324923
24884 try sema.safetyPanic(&fail_block, panic_id);24924 try sema.safetyPanic(&fail_block, src, panic_id);
24885 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);24925 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
24886}24926}
2488724927
...@@ -24940,7 +24980,7 @@ fn addSafetyCheckExtra(...@@ -24940,7 +24980,7 @@ fn addSafetyCheckExtra(
24940 parent_block.instructions.appendAssumeCapacity(block_inst);24980 parent_block.instructions.appendAssumeCapacity(block_inst);
24941}24981}
2494224982
24943fn panicWithMsg(sema: *Sema, block: *Block, msg_inst: Air.Inst.Ref) !void {24983fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void {
24944 const mod = sema.mod;24984 const mod = sema.mod;
2494524985
24946 if (!mod.backendSupportsFeature(.panic_fn)) {24986 if (!mod.backendSupportsFeature(.panic_fn)) {
...@@ -24959,12 +24999,13 @@ fn panicWithMsg(sema: *Sema, block: *Block, msg_inst: Air.Inst.Ref) !void {...@@ -24959,12 +24999,13 @@ fn panicWithMsg(sema: *Sema, block: *Block, msg_inst: Air.Inst.Ref) !void {
24959 .ty = opt_usize_ty.toIntern(),24999 .ty = opt_usize_ty.toIntern(),
24960 .val = .none,25000 .val = .none,
24961 } })).toValue());25001 } })).toValue());
24962 try sema.callBuiltin(block, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr });25002 try sema.callBuiltin(block, src, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr }, operation);
24963}25003}
2496425004
24965fn panicUnwrapError(25005fn panicUnwrapError(
24966 sema: *Sema,25006 sema: *Sema,
24967 parent_block: *Block,25007 parent_block: *Block,
25008 src: LazySrcLoc,
24968 operand: Air.Inst.Ref,25009 operand: Air.Inst.Ref,
24969 unwrap_err_tag: Air.Inst.Tag,25010 unwrap_err_tag: Air.Inst.Tag,
24970 is_non_err_tag: Air.Inst.Tag,25011 is_non_err_tag: Air.Inst.Tag,
...@@ -24972,7 +25013,7 @@ fn panicUnwrapError(...@@ -24972,7 +25013,7 @@ fn panicUnwrapError(
24972 assert(!parent_block.is_comptime);25013 assert(!parent_block.is_comptime);
24973 const ok = try parent_block.addUnOp(is_non_err_tag, operand);25014 const ok = try parent_block.addUnOp(is_non_err_tag, operand);
24974 if (!sema.mod.comp.formatted_panics) {25015 if (!sema.mod.comp.formatted_panics) {
24975 return sema.addSafetyCheck(parent_block, ok, .unwrap_error);25016 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);
24976 }25017 }
24977 const gpa = sema.gpa;25018 const gpa = sema.gpa;
2497825019
...@@ -24997,7 +25038,7 @@ fn panicUnwrapError(...@@ -24997,7 +25038,7 @@ fn panicUnwrapError(
24997 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);25038 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
24998 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);25039 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
24999 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };25040 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
25000 try sema.callBuiltin(&fail_block, panic_fn, .auto, &args);25041 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, &args, .@"safety check");
25001 }25042 }
25002 }25043 }
25003 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);25044 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -25006,6 +25047,7 @@ fn panicUnwrapError(...@@ -25006,6 +25047,7 @@ fn panicUnwrapError(
25006fn panicIndexOutOfBounds(25047fn panicIndexOutOfBounds(
25007 sema: *Sema,25048 sema: *Sema,
25008 parent_block: *Block,25049 parent_block: *Block,
25050 src: LazySrcLoc,
25009 index: Air.Inst.Ref,25051 index: Air.Inst.Ref,
25010 len: Air.Inst.Ref,25052 len: Air.Inst.Ref,
25011 cmp_op: Air.Inst.Tag,25053 cmp_op: Air.Inst.Tag,
...@@ -25013,28 +25055,30 @@ fn panicIndexOutOfBounds(...@@ -25013,28 +25055,30 @@ fn panicIndexOutOfBounds(
25013 assert(!parent_block.is_comptime);25055 assert(!parent_block.is_comptime);
25014 const ok = try parent_block.addBinOp(cmp_op, index, len);25056 const ok = try parent_block.addBinOp(cmp_op, index, len);
25015 if (!sema.mod.comp.formatted_panics) {25057 if (!sema.mod.comp.formatted_panics) {
25016 return sema.addSafetyCheck(parent_block, ok, .index_out_of_bounds);25058 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);
25017 }25059 }
25018 try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len });25060 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });
25019}25061}
2502025062
25021fn panicInactiveUnionField(25063fn panicInactiveUnionField(
25022 sema: *Sema,25064 sema: *Sema,
25023 parent_block: *Block,25065 parent_block: *Block,
25066 src: LazySrcLoc,
25024 active_tag: Air.Inst.Ref,25067 active_tag: Air.Inst.Ref,
25025 wanted_tag: Air.Inst.Ref,25068 wanted_tag: Air.Inst.Ref,
25026) !void {25069) !void {
25027 assert(!parent_block.is_comptime);25070 assert(!parent_block.is_comptime);
25028 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);25071 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
25029 if (!sema.mod.comp.formatted_panics) {25072 if (!sema.mod.comp.formatted_panics) {
25030 return sema.addSafetyCheck(parent_block, ok, .inactive_union_field);25073 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);
25031 }25074 }
25032 try sema.safetyCheckFormatted(parent_block, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });25075 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });
25033}25076}
2503425077
25035fn panicSentinelMismatch(25078fn panicSentinelMismatch(
25036 sema: *Sema,25079 sema: *Sema,
25037 parent_block: *Block,25080 parent_block: *Block,
25081 src: LazySrcLoc,
25038 maybe_sentinel: ?Value,25082 maybe_sentinel: ?Value,
25039 sentinel_ty: Type,25083 sentinel_ty: Type,
25040 ptr: Air.Inst.Ref,25084 ptr: Air.Inst.Ref,
...@@ -25069,19 +25113,20 @@ fn panicSentinelMismatch(...@@ -25069,19 +25113,20 @@ fn panicSentinelMismatch(
25069 else {25113 else {
25070 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");25114 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
25071 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };25115 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
25072 try sema.callBuiltin(parent_block, panic_fn, .auto, &args);25116 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
25073 return;25117 return;
25074 };25118 };
2507525119
25076 if (!sema.mod.comp.formatted_panics) {25120 if (!sema.mod.comp.formatted_panics) {
25077 return sema.addSafetyCheck(parent_block, ok, .sentinel_mismatch);25121 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);
25078 }25122 }
25079 try sema.safetyCheckFormatted(parent_block, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });25123 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });
25080}25124}
2508125125
25082fn safetyCheckFormatted(25126fn safetyCheckFormatted(
25083 sema: *Sema,25127 sema: *Sema,
25084 parent_block: *Block,25128 parent_block: *Block,
25129 src: LazySrcLoc,
25085 ok: Air.Inst.Ref,25130 ok: Air.Inst.Ref,
25086 func: []const u8,25131 func: []const u8,
25087 args: []const Air.Inst.Ref,25132 args: []const Air.Inst.Ref,
...@@ -25106,15 +25151,15 @@ fn safetyCheckFormatted(...@@ -25106,15 +25151,15 @@ fn safetyCheckFormatted(
25106 _ = try fail_block.addNoOp(.trap);25151 _ = try fail_block.addNoOp(.trap);
25107 } else {25152 } else {
25108 const panic_fn = try sema.getBuiltin(func);25153 const panic_fn = try sema.getBuiltin(func);
25109 try sema.callBuiltin(&fail_block, panic_fn, .auto, args);25154 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");
25110 }25155 }
25111 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);25156 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
25112}25157}
2511325158
25114fn safetyPanic(sema: *Sema, block: *Block, panic_id: Module.PanicId) CompileError!void {25159fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {
25115 const msg_decl_index = try sema.preparePanicId(block, panic_id);25160 const msg_decl_index = try sema.preparePanicId(block, panic_id);
25116 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);25161 const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index);
25117 try sema.panicWithMsg(block, msg_inst);25162 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
25118}25163}
2511925164
25120fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {25165fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
...@@ -26199,7 +26244,7 @@ fn unionFieldPtr(...@@ -26199,7 +26244,7 @@ fn unionFieldPtr(
26199 // TODO would it be better if get_union_tag supported pointers to unions?26244 // TODO would it be better if get_union_tag supported pointers to unions?
26200 const union_val = try block.addTyOp(.load, union_ty, union_ptr);26245 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
26201 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);26246 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);
26202 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);26247 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);
26203 }26248 }
26204 if (field.ty.zigTypeTag(mod) == .NoReturn) {26249 if (field.ty.zigTypeTag(mod) == .NoReturn) {
26205 _ = try block.addNoOp(.unreach);26250 _ = try block.addNoOp(.unreach);
...@@ -26271,7 +26316,7 @@ fn unionFieldVal(...@@ -26271,7 +26316,7 @@ fn unionFieldVal(
26271 const wanted_tag_val = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);26316 const wanted_tag_val = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
26272 const wanted_tag = try sema.addConstant(wanted_tag_val);26317 const wanted_tag = try sema.addConstant(wanted_tag_val);
26273 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);26318 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
26274 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);26319 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);
26275 }26320 }
26276 if (field.ty.zigTypeTag(mod) == .NoReturn) {26321 if (field.ty.zigTypeTag(mod) == .NoReturn) {
26277 _ = try block.addNoOp(.unreach);26322 _ = try block.addNoOp(.unreach);
...@@ -26626,7 +26671,7 @@ fn elemValArray(...@@ -26626,7 +26671,7 @@ fn elemValArray(
26626 if (maybe_index_val == null) {26671 if (maybe_index_val == null) {
26627 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);26672 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);
26628 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;26673 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;
26629 try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op);26674 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
26630 }26675 }
26631 }26676 }
26632 return block.addBinOp(.array_elem_val, array, elem_index);26677 return block.addBinOp(.array_elem_val, array, elem_index);
...@@ -26688,7 +26733,7 @@ fn elemPtrArray(...@@ -26688,7 +26733,7 @@ fn elemPtrArray(
26688 if (oob_safety and block.wantSafety() and offset == null) {26733 if (oob_safety and block.wantSafety() and offset == null) {
26689 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);26734 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);
26690 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;26735 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
26691 try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op);26736 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
26692 }26737 }
2669326738
26694 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);26739 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);
...@@ -26746,7 +26791,7 @@ fn elemValSlice(...@@ -26746,7 +26791,7 @@ fn elemValSlice(
26746 else26791 else
26747 try block.addTyOp(.slice_len, Type.usize, slice);26792 try block.addTyOp(.slice_len, Type.usize, slice);
26748 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;26793 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
26749 try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op);26794 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
26750 }26795 }
26751 try sema.queueFullTypeResolution(sema.typeOf(slice));26796 try sema.queueFullTypeResolution(sema.typeOf(slice));
26752 return block.addBinOp(.slice_elem_val, slice, elem_index);26797 return block.addBinOp(.slice_elem_val, slice, elem_index);
...@@ -26806,7 +26851,7 @@ fn elemPtrSlice(...@@ -26806,7 +26851,7 @@ fn elemPtrSlice(
26806 break :len try block.addTyOp(.slice_len, Type.usize, slice);26851 break :len try block.addTyOp(.slice_len, Type.usize, slice);
26807 };26852 };
26808 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;26853 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
26809 try sema.panicIndexOutOfBounds(block, elem_index, len_inst, cmp_op);26854 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
26810 }26855 }
26811 return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty);26856 return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty);
26812}26857}
...@@ -29705,7 +29750,7 @@ fn coerceCompatiblePtrs(...@@ -29705,7 +29750,7 @@ fn coerceCompatiblePtrs(
29705 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);29750 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
29706 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);29751 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
29707 } else is_non_zero;29752 } else is_non_zero;
29708 try sema.addSafetyCheck(block, ok, .cast_to_null);29753 try sema.addSafetyCheck(block, inst_src, ok, .cast_to_null);
29709 }29754 }
29710 return sema.bitCast(block, dest_ty, inst, inst_src, null);29755 return sema.bitCast(block, dest_ty, inst, inst_src, null);
29711}29756}
...@@ -31134,9 +31179,9 @@ fn analyzeSlice(...@@ -31134,9 +31179,9 @@ fn analyzeSlice(
31134 try sema.requireRuntimeBlock(block, src, runtime_src.?);31179 try sema.requireRuntimeBlock(block, src, runtime_src.?);
31135 const ok = try block.addBinOp(.cmp_lte, start, end);31180 const ok = try block.addBinOp(.cmp_lte, start, end);
31136 if (!sema.mod.comp.formatted_panics) {31181 if (!sema.mod.comp.formatted_panics) {
31137 try sema.addSafetyCheck(block, ok, .start_index_greater_than_end);31182 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);
31138 } else {31183 } else {
31139 try sema.safetyCheckFormatted(block, ok, "panicStartGreaterThanEnd", &.{ start, end });31184 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });
31140 }31185 }
31141 }31186 }
31142 const new_len = if (by_length)31187 const new_len = if (by_length)
...@@ -31173,7 +31218,7 @@ fn analyzeSlice(...@@ -31173,7 +31218,7 @@ fn analyzeSlice(
31173 // requirement: slicing C ptr is non-null31218 // requirement: slicing C ptr is non-null
31174 if (ptr_ptr_child_ty.isCPtr(mod)) {31219 if (ptr_ptr_child_ty.isCPtr(mod)) {
31175 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);31220 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
31176 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);31221 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
31177 }31222 }
3117831223
31179 if (slice_ty.isSlice(mod)) {31224 if (slice_ty.isSlice(mod)) {
...@@ -31188,11 +31233,11 @@ fn analyzeSlice(...@@ -31188,11 +31233,11 @@ fn analyzeSlice(
31188 else31233 else
31189 end;31234 end;
3119031235
31191 try sema.panicIndexOutOfBounds(block, actual_end, actual_len, .cmp_lte);31236 try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte);
31192 }31237 }
3119331238
31194 // requirement: result[new_len] == slice_sentinel31239 // requirement: result[new_len] == slice_sentinel
31195 try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len);31240 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
31196 }31241 }
31197 return result;31242 return result;
31198 };31243 };
...@@ -31230,7 +31275,7 @@ fn analyzeSlice(...@@ -31230,7 +31275,7 @@ fn analyzeSlice(
31230 // requirement: slicing C ptr is non-null31275 // requirement: slicing C ptr is non-null
31231 if (ptr_ptr_child_ty.isCPtr(mod)) {31276 if (ptr_ptr_child_ty.isCPtr(mod)) {
31232 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);31277 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
31233 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);31278 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
31234 }31279 }
3123531280
31236 // requirement: end <= len31281 // requirement: end <= len
...@@ -31254,11 +31299,11 @@ fn analyzeSlice(...@@ -31254,11 +31299,11 @@ fn analyzeSlice(
31254 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)31299 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)
31255 else31300 else
31256 end;31301 end;
31257 try sema.panicIndexOutOfBounds(block, actual_end, len_inst, .cmp_lte);31302 try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte);
31258 }31303 }
3125931304
31260 // requirement: start <= end31305 // requirement: start <= end
31261 try sema.panicIndexOutOfBounds(block, start, end, .cmp_lte);31306 try sema.panicIndexOutOfBounds(block, src, start, end, .cmp_lte);
31262 }31307 }
31263 const result = try block.addInst(.{31308 const result = try block.addInst(.{
31264 .tag = .slice,31309 .tag = .slice,
...@@ -31272,7 +31317,7 @@ fn analyzeSlice(...@@ -31272,7 +31317,7 @@ fn analyzeSlice(
31272 });31317 });
31273 if (block.wantSafety()) {31318 if (block.wantSafety()) {
31274 // requirement: result[new_len] == slice_sentinel31319 // requirement: result[new_len] == slice_sentinel
31275 try sema.panicSentinelMismatch(block, slice_sentinel, elem_ty, result, new_len);31320 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
31276 }31321 }
31277 return result;31322 return result;
31278}31323}
test/cases/compile_errors/call_from_naked_func.zig created+24
...@@ -0,0 +1,24 @@
1export fn runtimeCall() callconv(.Naked) void {
2 f();
3}
4
5export fn runtimeBuiltinCall() callconv(.Naked) void {
6 @call(.auto, f, .{});
7}
8
9export fn comptimeCall() callconv(.Naked) void {
10 comptime f();
11}
12
13export fn comptimeBuiltinCall() callconv(.Naked) void {
14 @call(.compile_time, f, .{});
15}
16
17fn f() void {}
18
19// error
20// backend=llvm
21// target=native
22//
23// :2:6: error: runtime call not allowed in naked function
24// :6:5: error: runtime @call not allowed in naked function
test/cases/compile_errors/return_from_naked_function.zig created+14
...@@ -0,0 +1,14 @@
1fn foo() callconv(.Naked) void {
2 return;
3}
4
5comptime {
6 _ = &foo;
7}
8
9// error
10// backend=llvm
11// target=native
12//
13// :2:5: error: cannot return from naked function
14// :2:5: note: can only return using assembly
test/cases/compile_errors/unreachable_in_naked_func.zig created+30
...@@ -0,0 +1,30 @@
1fn runtimeSafetyDefault() callconv(.Naked) void {
2 unreachable;
3}
4
5fn runtimeSafetyOn() callconv(.Naked) void {
6 @setRuntimeSafety(true);
7 unreachable;
8}
9
10fn runtimeSafetyOff() callconv(.Naked) void {
11 @setRuntimeSafety(false);
12 unreachable;
13}
14
15comptime {
16 _ = &runtimeSafetyDefault;
17 _ = &runtimeSafetyOn;
18 _ = &runtimeSafetyOff;
19}
20
21// error
22// backend=llvm
23// target=native
24//
25// :2:5: error: runtime safety check not allowed in naked function
26// :2:5: note: use @setRuntimeSafety to disable runtime safety
27// :2:5: note: the end of a naked function is implicitly unreachable
28// :7:5: error: runtime safety check not allowed in naked function
29// :7:5: note: use @setRuntimeSafety to disable runtime safety
30// :7:5: note: the end of a naked function is implicitly unreachable