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 {
745745 return result_index;
746746 }
747747
748 fn addUnreachable(block: *Block, safety_check: bool) !void {
748 fn addUnreachable(block: *Block, src: LazySrcLoc, safety_check: bool) !void {
749749 if (safety_check and block.wantSafety()) {
750 try block.sema.safetyPanic(block, .unreach);
750 try block.sema.safetyPanic(block, src, .unreach);
751751 } else {
752752 _ = try block.addNoOp(.unreach);
753753 }
......@@ -4304,7 +4304,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
43044304 if (arg_len == .none) continue;
43054305 if (i == len_idx) continue;
43064306 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);
43084308 }
43094309 }
43104310
......@@ -5442,7 +5442,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I
54425442 if (block.is_comptime) {
54435443 return sema.fail(block, src, "encountered @panic at comptime", .{});
54445444 }
5445 try sema.panicWithMsg(block, msg_inst);
5445 try sema.panicWithMsg(block, src, msg_inst, .@"@panic");
54465446 return always_noreturn;
54475447}
54485448
......@@ -6605,7 +6605,7 @@ fn zirCall(
66056605 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))
66066606 {
66076607 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);
66096609 };
66106610
66116611 const return_ty = sema.typeOf(call_inst);
......@@ -6635,11 +6635,11 @@ fn zirCall(
66356635 }
66366636
66376637 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
66406640 return call_inst;
66416641 } 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);
66436643 }
66446644}
66456645
......@@ -6719,9 +6719,11 @@ fn checkCallArgumentCount(
67196719fn callBuiltin(
67206720 sema: *Sema,
67216721 block: *Block,
6722 call_src: LazySrcLoc,
67226723 builtin_fn: Air.Inst.Ref,
67236724 modifier: std.builtin.CallModifier,
67246725 args: []const Air.Inst.Ref,
6726 operation: CallOperation,
67256727) !void {
67266728 const mod = sema.mod;
67276729 const callee_ty = sema.typeOf(builtin_fn);
......@@ -6744,9 +6746,17 @@ fn callBuiltin(
67446746 if (args.len != fn_params_len or (func_ty_info.is_var_args and args.len < fn_params_len)) {
67456747 std.debug.panic("parameter count mismatch calling builtin fn, expected {d}, found {d}", .{ fn_params_len, args.len });
67466748 }
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);
67486750}
67496751
6752const CallOperation = enum {
6753 call,
6754 @"@call",
6755 @"@panic",
6756 @"safety check",
6757 @"error return",
6758};
6759
67506760fn analyzeCall(
67516761 sema: *Sema,
67526762 block: *Block,
......@@ -6759,6 +6769,7 @@ fn analyzeCall(
67596769 uncasted_args: []const Air.Inst.Ref,
67606770 bound_arg_src: ?LazySrcLoc,
67616771 call_dbg_node: ?Zir.Inst.Index,
6772 operation: CallOperation,
67626773) CompileError!Air.Inst.Ref {
67636774 const mod = sema.mod;
67646775 const ip = &mod.intern_pool;
......@@ -6830,7 +6841,17 @@ fn analyzeCall(
68306841 func_ty_info.cc == .Inline;
68316842
68326843 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);
68346855 }
68356856
68366857 if (!is_inline_call and is_generic_call) {
......@@ -7281,7 +7302,7 @@ fn analyzeCall(
72817302 else => {},
72827303 }
72837304 }
7284 try sema.safetyPanic(block, .noreturn_returned);
7305 try sema.safetyPanic(block, call_src, .noreturn_returned);
72857306 return Air.Inst.Ref.unreachable_value;
72867307 }
72877308 if (func_ty_info.return_type == .noreturn_type) {
......@@ -7939,7 +7960,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
79397960 const zero_val = try sema.addConstant(try mod.intValue(Type.err_int, 0));
79407961 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
79417962 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);
79437964 }
79447965 return block.addInst(.{
79457966 .tag = .bitcast,
......@@ -8131,7 +8152,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
81318152 mod.backendSupportsFeature(.is_named_enum_value))
81328153 {
81338154 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);
81358156 }
81368157 return result;
81378158}
......@@ -8207,7 +8228,7 @@ fn analyzeOptionalPayloadPtr(
82078228 try sema.requireRuntimeBlock(block, src, null);
82088229 if (safety_check and block.wantSafety()) {
82098230 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);
82118232 }
82128233 const air_tag: Air.Inst.Tag = if (initializing)
82138234 .optional_payload_ptr_set
......@@ -8264,7 +8285,7 @@ fn zirOptionalPayload(
82648285 try sema.requireRuntimeBlock(block, src, null);
82658286 if (safety_check and block.wantSafety()) {
82668287 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);
82688289 }
82698290 return block.addTyOp(.optional_payload, result_ty, operand);
82708291}
......@@ -8318,7 +8339,7 @@ fn analyzeErrUnionPayload(
83188339 if (safety_check and block.wantSafety() and
83198340 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
83208341 {
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);
83228343 }
83238344
83248345 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);
......@@ -8399,7 +8420,7 @@ fn analyzeErrUnionPayloadPtr(
83998420 if (safety_check and block.wantSafety() and
84008421 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
84018422 {
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);
84038424 }
84048425
84058426 const air_tag: Air.Inst.Tag = if (initializing)
......@@ -9637,7 +9658,7 @@ fn intCast(
96379658 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
96389659 break :ok is_in_range;
96399660 };
9640 try sema.addSafetyCheck(block, ok, .cast_truncated_data);
9661 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
96419662 }
96429663 }
96439664
......@@ -9691,7 +9712,7 @@ fn intCast(
96919712 break :ok is_in_range;
96929713 };
96939714 // TODO negative_to_unsigned?
9694 try sema.addSafetyCheck(block, ok, .cast_truncated_data);
9715 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
96959716 } else {
96969717 const ok = if (is_vector) ok: {
96979718 const is_in_range = try block.addCmpVector(diff, dest_max, .lte);
......@@ -9707,7 +9728,7 @@ fn intCast(
97079728 const is_in_range = try block.addBinOp(.cmp_lte, diff, dest_max);
97089729 break :ok is_in_range;
97099730 };
9710 try sema.addSafetyCheck(block, ok, .cast_truncated_data);
9731 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
97119732 }
97129733 } else if (actual_info.signedness == .signed and wanted_info.signedness == .unsigned) {
97139734 // no shrinkage, yes sign loss
......@@ -9730,7 +9751,7 @@ fn intCast(
97309751 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);
97319752 break :ok is_in_range;
97329753 };
9733 try sema.addSafetyCheck(block, ok, .negative_to_unsigned);
9754 try sema.addSafetyCheck(block, src, ok, .negative_to_unsigned);
97349755 }
97359756 }
97369757 return block.addTyOp(.intcast, dest_ty, operand);
......@@ -10319,7 +10340,7 @@ const SwitchProngAnalysis = struct {
1031910340 .ErrorSet => if (spa.else_error_ty) |ty| {
1032010341 return sema.bitCast(block, ty, spa.operand, operand_src, null);
1032110342 } else {
10322 try block.addUnreachable(false);
10343 try block.addUnreachable(operand_src, false);
1032310344 return Air.Inst.Ref.unreachable_value;
1032410345 },
1032510346 else => return spa.operand,
......@@ -11475,7 +11496,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1147511496 if (special_prong == .none) {
1147611497 return sema.fail(block, src, "switch must handle all possibilities", .{});
1147711498 }
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)) {
1147911500 return Air.Inst.Ref.unreachable_value;
1148011501 }
1148111502 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
1148311504 {
1148411505 try sema.zirDbgStmt(block, cond_dbg_node_index);
1148511506 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);
1148711508 }
1148811509
1148911510 return spa.resolveProngComptime(
......@@ -11543,7 +11564,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1154311564 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
1154411565 } 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)) {
1154711568 // nothing to do here
1154811569 } else if (analyze_body) {
1154911570 try spa.analyzeProngRuntime(
......@@ -11725,7 +11746,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1172511746
1172611747 const body = sema.code.extra[extra_index..][0..info.body_len];
1172711748 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)) {
1172911750 // nothing to do here
1173011751 } else if (analyze_body) {
1173111752 try spa.analyzeProngRuntime(
......@@ -11812,7 +11833,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1181211833
1181311834 const body = sema.code.extra[extra_index..][0..info.body_len];
1181411835 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)) {
1181611837 // nothing to do here
1181711838 } else {
1181811839 try spa.analyzeProngRuntime(
......@@ -12045,7 +12066,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1204512066 {
1204612067 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
1204712068 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);
1204912070 }
1205012071
1205112072 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
1205812079 else
1205912080 true;
1206012081 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))
1206212083 {
1206312084 // nothing to do here
1206412085 } 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
1207712098 // that it is unreachable.
1207812099 if (case_block.wantSafety()) {
1207912100 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);
1208112102 } else {
1208212103 _ = try case_block.addNoOp(.unreach);
1208312104 }
......@@ -12420,7 +12441,7 @@ fn validateSwitchNoRange(
1242012441 return sema.failWithOwnedErrorMsg(msg);
1242112442}
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 {
1242412445 const mod = sema.mod;
1242512446 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
1245912480 .field_val => try sema.zirFieldVal(block, inst),
1246012481 .@"unreachable" => {
1246112482 if (!mod.comp.formatted_panics) {
12462 try sema.safetyPanic(block, .unwrap_error);
12483 try sema.safetyPanic(block, operand_src, .unwrap_error);
1246312484 return true;
1246412485 }
1246512486
1246612487 const panic_fn = try sema.getBuiltin("panicUnwrapError");
1246712488 const err_return_trace = try sema.getErrorReturnTrace(block);
1246812489 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");
1247012491 return true;
1247112492 },
1247212493 .panic => {
......@@ -12476,7 +12497,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1247612497 const panic_fn = try sema.getBuiltin("panic");
1247712498 const err_return_trace = try sema.getErrorReturnTrace(block);
1247812499 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");
1248012501 return true;
1248112502 },
1248212503 else => unreachable,
......@@ -12851,7 +12872,7 @@ fn zirShl(
1285112872 const bit_count_inst = try sema.addConstant(bit_count_val);
1285212873 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
1285312874 };
12854 try sema.addSafetyCheck(block, ok, .shift_rhs_too_big);
12875 try sema.addSafetyCheck(block, src, ok, .shift_rhs_too_big);
1285512876 }
1285612877
1285712878 if (air_tag == .shl_exact) {
......@@ -12880,7 +12901,7 @@ fn zirShl(
1288012901 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));
1288112902 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);
1288412905 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);
1288512906 }
1288612907 }
......@@ -13001,7 +13022,7 @@ fn zirShr(
1300113022 const bit_count_inst = try sema.addConstant(bit_count_val);
1300213023 break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
1300313024 };
13004 try sema.addSafetyCheck(block, ok, .shift_rhs_too_big);
13025 try sema.addSafetyCheck(block, src, ok, .shift_rhs_too_big);
1300513026 }
1300613027
1300713028 if (air_tag == .shr_exact) {
......@@ -13017,7 +13038,7 @@ fn zirShr(
1301713038 } },
1301813039 });
1301913040 } 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);
1302113042 }
1302213043 }
1302313044 return result;
......@@ -13894,8 +13915,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1389413915 try sema.requireRuntimeBlock(block, src, runtime_src);
1389513916
1389613917 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);
13898 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, 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);
13919 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
1389913920 }
1390013921
1390113922 const air_tag = if (is_int) blk: {
......@@ -14025,8 +14046,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1402514046 // div_trunc and check for remainder.
1402614047
1402714048 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);
14029 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, 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);
14050 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
1403014051
1403114052 const result = try block.addBinOp(.div_trunc, casted_lhs, casted_rhs);
1403214053 const ok = if (!is_int) ok: {
......@@ -14076,7 +14097,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1407614097 break :ok is_in_range;
1407714098 }
1407814099 };
14079 try sema.addSafetyCheck(block, ok, .exact_division_remainder);
14100 try sema.addSafetyCheck(block, src, ok, .exact_division_remainder);
1408014101 return result;
1408114102 }
1408214103
......@@ -14191,8 +14212,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1419114212 try sema.requireRuntimeBlock(block, src, runtime_src);
1419214213
1419314214 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);
14195 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, 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);
14216 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
1419614217 }
1419714218
1419814219 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
1430814329 try sema.requireRuntimeBlock(block, src, runtime_src);
1430914330
1431014331 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);
14312 try sema.addDivByZeroSafety(block, resolved_type, maybe_rhs_val, 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);
14333 try sema.addDivByZeroSafety(block, src, resolved_type, maybe_rhs_val, casted_rhs, is_int);
1431314334 }
1431414335
1431514336 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
1431814339fn addDivIntOverflowSafety(
1431914340 sema: *Sema,
1432014341 block: *Block,
14342 src: LazySrcLoc,
1432114343 resolved_type: Type,
1432214344 lhs_scalar_ty: Type,
1432314345 maybe_lhs_val: ?Value,
......@@ -14391,12 +14413,13 @@ fn addDivIntOverflowSafety(
1439114413 }
1439214414 assert(ok != .none);
1439314415 }
14394 try sema.addSafetyCheck(block, ok, .integer_overflow);
14416 try sema.addSafetyCheck(block, src, ok, .integer_overflow);
1439514417}
1439614418
1439714419fn addDivByZeroSafety(
1439814420 sema: *Sema,
1439914421 block: *Block,
14422 src: LazySrcLoc,
1440014423 resolved_type: Type,
1440114424 maybe_rhs_val: ?Value,
1440214425 casted_rhs: Air.Inst.Ref,
......@@ -14429,7 +14452,7 @@ fn addDivByZeroSafety(
1442914452 const zero = try sema.addConstant(scalar_zero);
1443014453 break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);
1443114454 };
14432 try sema.addSafetyCheck(block, ok, .divide_by_zero);
14455 try sema.addSafetyCheck(block, src, ok, .divide_by_zero);
1443314456}
1443414457
1443514458fn 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.
1456914592 try sema.requireRuntimeBlock(block, src, runtime_src);
1457014593
1457114594 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);
1457314596 }
1457414597
1457514598 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
1472014743 try sema.requireRuntimeBlock(block, src, runtime_src);
1472114744
1472214745 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);
1472414747 }
1472514748
1472614749 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
1482014843 try sema.requireRuntimeBlock(block, src, runtime_src);
1482114844
1482214845 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);
1482414847 }
1482514848
1482614849 const air_tag = airTag(block, is_int, .rem, .rem_optimized);
......@@ -15558,7 +15581,7 @@ fn analyzeArithmetic(
1555815581 const zero_ov = try sema.addConstant(try mod.intValue(Type.u1, 0));
1555915582 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);
1556215585 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);
1556315586 }
1556415587 }
......@@ -17979,7 +18002,7 @@ fn zirCondbr(
1797918002 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
1798018003 };
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)) {
1798318006 // nothing to do
1798418007 } else {
1798518008 try sema.analyzeBodyRuntimeBreak(&sub_block, else_body);
......@@ -18171,7 +18194,15 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1817118194 return sema.fail(block, src, "reached unreachable code", .{});
1817218195 }
1817318196 // 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 };
1817518206 return always_noreturn;
1817618207}
1817718208
......@@ -18202,21 +18233,21 @@ fn zirRetImplicit(
1820218233 const tracy = trace(@src());
1820318234 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();
1820518239 if (block.inlining == null and sema.func_is_naked) {
1820618240 assert(!block.is_comptime);
1820718241 if (block.wantSafety()) {
1820818242 // Calling a safety function from a naked function would not be legal.
1820918243 _ = try block.addNoOp(.trap);
1821018244 } else {
18211 try block.addUnreachable(false);
18245 try block.addUnreachable(r_brace_src, false);
1821218246 }
1821318247 return always_noreturn;
1821418248 }
1821518249
18216 const mod = sema.mod;
18217 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1821818250 const operand = try sema.resolveInst(inst_data.operand);
18219 const r_brace_src = inst_data.src();
1822018251 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
1822118252 const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod);
1822218253 if (base_tag == .NoReturn) {
......@@ -18270,7 +18301,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1827018301
1827118302 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
1827218303 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);
1827418305 }
1827518306
1827618307 _ = try block.addUnOp(.ret_load, ret_ptr);
......@@ -18280,6 +18311,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1828018311fn retWithErrTracing(
1828118312 sema: *Sema,
1828218313 block: *Block,
18314 src: LazySrcLoc,
1828318315 is_non_err: Air.Inst.Ref,
1828418316 ret_tag: Air.Inst.Tag,
1828518317 operand: Air.Inst.Ref,
......@@ -18302,7 +18334,7 @@ fn retWithErrTracing(
1830218334 const args: [1]Air.Inst.Ref = .{err_return_trace};
1830318335
1830418336 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");
1830618338 _ = try block.addUnOp(ret_tag, operand);
1830718339 return always_noreturn;
1830818340 }
......@@ -18313,7 +18345,7 @@ fn retWithErrTracing(
1831318345
1831418346 var else_block = block.makeSubBlock();
1831518347 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");
1831718349 _ = try else_block.addUnOp(ret_tag, operand);
1831818350
1831918351 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
......@@ -18470,7 +18502,14 @@ fn analyzeRet(
1847018502 } else if (block.is_comptime) {
1847118503 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});
1847218504 } 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);
1847418513 }
1847518514
1847618515 try sema.resolveTypeLayout(sema.fn_ret_ty);
......@@ -18479,7 +18518,7 @@ fn analyzeRet(
1847918518 // Avoid adding a frame to the error return trace in case the value is comptime-known
1848018519 // to be not an error.
1848118520 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);
1848318522 }
1848418523
1848518524 _ = try block.addUnOp(.ret, operand);
......@@ -19624,7 +19663,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1962419663 try sema.requireRuntimeBlock(block, src, operand_src);
1962519664 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {
1962619665 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);
1962819667 }
1962919668 // In case the value is runtime-known, we have an AIR instruction for this instead
1963019669 // 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
2076920808 if (dest_ty.intInfo(mod).bits == 0) {
2077020809 if (block.wantSafety()) {
2077120810 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);
2077320812 }
2077420813 return sema.addConstant(try mod.intValue(dest_ty, 0));
2077520814 }
......@@ -20780,7 +20819,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2078020819 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)));
2078120820 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)));
2078220821 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);
2078420823 }
2078520824 return result;
2078620825}
......@@ -20857,7 +20896,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2085720896 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
2085820897 if (!ptr_ty.isAllowzeroPtr(mod)) {
2085920898 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);
2086120900 }
2086220901
2086320902 if (ptr_align > 1) {
......@@ -20866,7 +20905,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2086620905 );
2086720906 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
2086820907 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);
2087020909 }
2087120910 }
2087220911 return block.addBitCast(ptr_ty, operand_coerced);
......@@ -20954,7 +20993,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2095420993 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
2095520994 const err_int_inst = try block.addBitCast(Type.err_int, operand);
2095620995 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);
2095820997 }
2095920998 return block.addBitCast(dest_ty, operand);
2096020999}
......@@ -21300,7 +21339,7 @@ fn ptrCastFull(
2130021339 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
2130121340 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
2130221341 } else is_non_zero;
21303 try sema.addSafetyCheck(block, ok, .cast_to_null);
21342 try sema.addSafetyCheck(block, src, ok, .cast_to_null);
2130421343 }
2130521344
2130621345 if (block.wantSafety() and dest_align > src_align and try sema.typeHasRuntimeBits(dest_info.child.toType())) {
......@@ -21315,7 +21354,7 @@ fn ptrCastFull(
2131521354 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
2131621355 break :ok try block.addBinOp(.bit_or, len_zero, is_aligned);
2131721356 } else is_aligned;
21318 try sema.addSafetyCheck(block, ok, .incorrect_alignment);
21357 try sema.addSafetyCheck(block, src, ok, .incorrect_alignment);
2131921358 }
2132021359
2132121360 // 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
2299223031 const callee_ty = sema.typeOf(func);
2299323032 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);
2299423033 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");
2299623035}
2299723036
2299823037fn 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
2347723516
2347823517 if (block.wantSafety()) {
2347923518 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);
2348123520 }
2348223521 } else if (dest_len != .none) {
2348323522 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
2361923658 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);
2362023659 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);
2362123660 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);
2362323662 }
2362423663
2362523664 _ = try block.addInst(.{
......@@ -24862,6 +24901,7 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !Module.
2486224901fn addSafetyCheck(
2486324902 sema: *Sema,
2486424903 parent_block: *Block,
24904 src: LazySrcLoc,
2486524905 ok: Air.Inst.Ref,
2486624906 panic_id: Module.PanicId,
2486724907) !void {
......@@ -24881,7 +24921,7 @@ fn addSafetyCheck(
2488124921
2488224922 defer fail_block.instructions.deinit(gpa);
2488324923
24884 try sema.safetyPanic(&fail_block, panic_id);
24924 try sema.safetyPanic(&fail_block, src, panic_id);
2488524925 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
2488624926}
2488724927
......@@ -24940,7 +24980,7 @@ fn addSafetyCheckExtra(
2494024980 parent_block.instructions.appendAssumeCapacity(block_inst);
2494124981}
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 {
2494424984 const mod = sema.mod;
2494524985
2494624986 if (!mod.backendSupportsFeature(.panic_fn)) {
......@@ -24959,12 +24999,13 @@ fn panicWithMsg(sema: *Sema, block: *Block, msg_inst: Air.Inst.Ref) !void {
2495924999 .ty = opt_usize_ty.toIntern(),
2496025000 .val = .none,
2496125001 } })).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);
2496325003}
2496425004
2496525005fn panicUnwrapError(
2496625006 sema: *Sema,
2496725007 parent_block: *Block,
25008 src: LazySrcLoc,
2496825009 operand: Air.Inst.Ref,
2496925010 unwrap_err_tag: Air.Inst.Tag,
2497025011 is_non_err_tag: Air.Inst.Tag,
......@@ -24972,7 +25013,7 @@ fn panicUnwrapError(
2497225013 assert(!parent_block.is_comptime);
2497325014 const ok = try parent_block.addUnOp(is_non_err_tag, operand);
2497425015 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);
2497625017 }
2497725018 const gpa = sema.gpa;
2497825019
......@@ -24997,7 +25038,7 @@ fn panicUnwrapError(
2499725038 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
2499825039 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
2499925040 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");
2500125042 }
2500225043 }
2500325044 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
......@@ -25006,6 +25047,7 @@ fn panicUnwrapError(
2500625047fn panicIndexOutOfBounds(
2500725048 sema: *Sema,
2500825049 parent_block: *Block,
25050 src: LazySrcLoc,
2500925051 index: Air.Inst.Ref,
2501025052 len: Air.Inst.Ref,
2501125053 cmp_op: Air.Inst.Tag,
......@@ -25013,28 +25055,30 @@ fn panicIndexOutOfBounds(
2501325055 assert(!parent_block.is_comptime);
2501425056 const ok = try parent_block.addBinOp(cmp_op, index, len);
2501525057 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);
2501725059 }
25018 try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len });
25060 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });
2501925061}
2502025062
2502125063fn panicInactiveUnionField(
2502225064 sema: *Sema,
2502325065 parent_block: *Block,
25066 src: LazySrcLoc,
2502425067 active_tag: Air.Inst.Ref,
2502525068 wanted_tag: Air.Inst.Ref,
2502625069) !void {
2502725070 assert(!parent_block.is_comptime);
2502825071 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
2502925072 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);
2503125074 }
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 });
2503325076}
2503425077
2503525078fn panicSentinelMismatch(
2503625079 sema: *Sema,
2503725080 parent_block: *Block,
25081 src: LazySrcLoc,
2503825082 maybe_sentinel: ?Value,
2503925083 sentinel_ty: Type,
2504025084 ptr: Air.Inst.Ref,
......@@ -25069,19 +25113,20 @@ fn panicSentinelMismatch(
2506925113 else {
2507025114 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
2507125115 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");
2507325117 return;
2507425118 };
2507525119
2507625120 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);
2507825122 }
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 });
2508025124}
2508125125
2508225126fn safetyCheckFormatted(
2508325127 sema: *Sema,
2508425128 parent_block: *Block,
25129 src: LazySrcLoc,
2508525130 ok: Air.Inst.Ref,
2508625131 func: []const u8,
2508725132 args: []const Air.Inst.Ref,
......@@ -25106,15 +25151,15 @@ fn safetyCheckFormatted(
2510625151 _ = try fail_block.addNoOp(.trap);
2510725152 } else {
2510825153 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");
2511025155 }
2511125156 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
2511225157}
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 {
2511525160 const msg_decl_index = try sema.preparePanicId(block, panic_id);
25116 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);
25117 try sema.panicWithMsg(block, msg_inst);
25161 const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index);
25162 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
2511825163}
2511925164
2512025165fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
......@@ -26199,7 +26244,7 @@ fn unionFieldPtr(
2619926244 // TODO would it be better if get_union_tag supported pointers to unions?
2620026245 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
2620126246 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);
2620326248 }
2620426249 if (field.ty.zigTypeTag(mod) == .NoReturn) {
2620526250 _ = try block.addNoOp(.unreach);
......@@ -26271,7 +26316,7 @@ fn unionFieldVal(
2627126316 const wanted_tag_val = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2627226317 const wanted_tag = try sema.addConstant(wanted_tag_val);
2627326318 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);
2627526320 }
2627626321 if (field.ty.zigTypeTag(mod) == .NoReturn) {
2627726322 _ = try block.addNoOp(.unreach);
......@@ -26626,7 +26671,7 @@ fn elemValArray(
2662626671 if (maybe_index_val == null) {
2662726672 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);
2662826673 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);
2663026675 }
2663126676 }
2663226677 return block.addBinOp(.array_elem_val, array, elem_index);
......@@ -26688,7 +26733,7 @@ fn elemPtrArray(
2668826733 if (oob_safety and block.wantSafety() and offset == null) {
2668926734 const len_inst = try sema.addIntUnsigned(Type.usize, array_len);
2669026735 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);
2669226737 }
2669326738
2669426739 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);
......@@ -26746,7 +26791,7 @@ fn elemValSlice(
2674626791 else
2674726792 try block.addTyOp(.slice_len, Type.usize, slice);
2674826793 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);
2675026795 }
2675126796 try sema.queueFullTypeResolution(sema.typeOf(slice));
2675226797 return block.addBinOp(.slice_elem_val, slice, elem_index);
......@@ -26806,7 +26851,7 @@ fn elemPtrSlice(
2680626851 break :len try block.addTyOp(.slice_len, Type.usize, slice);
2680726852 };
2680826853 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);
2681026855 }
2681126856 return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty);
2681226857}
......@@ -29705,7 +29750,7 @@ fn coerceCompatiblePtrs(
2970529750 const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
2970629751 break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
2970729752 } else is_non_zero;
29708 try sema.addSafetyCheck(block, ok, .cast_to_null);
29753 try sema.addSafetyCheck(block, inst_src, ok, .cast_to_null);
2970929754 }
2971029755 return sema.bitCast(block, dest_ty, inst, inst_src, null);
2971129756}
......@@ -31134,9 +31179,9 @@ fn analyzeSlice(
3113431179 try sema.requireRuntimeBlock(block, src, runtime_src.?);
3113531180 const ok = try block.addBinOp(.cmp_lte, start, end);
3113631181 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);
3113831183 } else {
31139 try sema.safetyCheckFormatted(block, ok, "panicStartGreaterThanEnd", &.{ start, end });
31184 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });
3114031185 }
3114131186 }
3114231187 const new_len = if (by_length)
......@@ -31173,7 +31218,7 @@ fn analyzeSlice(
3117331218 // requirement: slicing C ptr is non-null
3117431219 if (ptr_ptr_child_ty.isCPtr(mod)) {
3117531220 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);
3117731222 }
3117831223
3117931224 if (slice_ty.isSlice(mod)) {
......@@ -31188,11 +31233,11 @@ fn analyzeSlice(
3118831233 else
3118931234 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);
3119231237 }
3119331238
3119431239 // 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);
3119631241 }
3119731242 return result;
3119831243 };
......@@ -31230,7 +31275,7 @@ fn analyzeSlice(
3123031275 // requirement: slicing C ptr is non-null
3123131276 if (ptr_ptr_child_ty.isCPtr(mod)) {
3123231277 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);
3123431279 }
3123531280
3123631281 // requirement: end <= len
......@@ -31254,11 +31299,11 @@ fn analyzeSlice(
3125431299 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)
3125531300 else
3125631301 end;
31257 try sema.panicIndexOutOfBounds(block, actual_end, len_inst, .cmp_lte);
31302 try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte);
3125831303 }
3125931304
3126031305 // requirement: start <= end
31261 try sema.panicIndexOutOfBounds(block, start, end, .cmp_lte);
31306 try sema.panicIndexOutOfBounds(block, src, start, end, .cmp_lte);
3126231307 }
3126331308 const result = try block.addInst(.{
3126431309 .tag = .slice,
......@@ -31272,7 +31317,7 @@ fn analyzeSlice(
3127231317 });
3127331318 if (block.wantSafety()) {
3127431319 // 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);
3127631321 }
3127731322 return result;
3127831323}
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