| ... | ... | @@ -30,6 +30,8 @@ owner_func_index: InternPool.Index, |
| 30 | 30 | /// an inline or comptime function call. |
| 31 | 31 | /// This could be `none`, a `func_decl`, or a `func_instance`. |
| 32 | 32 | func_index: InternPool.Index, |
| 33 | /// Whether the type of func_index has a calling convention of `.Naked`. |
| 34 | func_is_naked: bool, |
| 33 | 35 | /// Used to restore the error return trace when returning a non-error from a function. |
| 34 | 36 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, |
| 35 | 37 | /// When semantic analysis needs to know the return type of the function whose body |
| ... | ... | @@ -6827,6 +6829,10 @@ fn analyzeCall( |
| 6827 | 6829 | var is_inline_call = is_comptime_call or modifier == .always_inline or |
| 6828 | 6830 | func_ty_info.cc == .Inline; |
| 6829 | 6831 | |
| 6832 | 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", .{}); |
| 6834 | } |
| 6835 | |
| 6830 | 6836 | if (!is_inline_call and is_generic_call) { |
| 6831 | 6837 | if (sema.instantiateGenericCall( |
| 6832 | 6838 | block, |
| ... | ... | @@ -7509,6 +7515,9 @@ fn instantiateGenericCall( |
| 7509 | 7515 | .owner_decl = sema.owner_decl, |
| 7510 | 7516 | .owner_decl_index = sema.owner_decl_index, |
| 7511 | 7517 | .func_index = sema.owner_func_index, |
| 7518 | // This may not be known yet, since the calling convention could be generic, but there |
| 7519 | // should be no illegal instructions encountered while creating the function anyway. |
| 7520 | .func_is_naked = false, |
| 7512 | 7521 | .fn_ret_ty = Type.void, |
| 7513 | 7522 | .fn_ret_ty_ies = null, |
| 7514 | 7523 | .owner_func_index = .none, |
| ... | ... | @@ -18193,10 +18202,20 @@ fn zirRetImplicit( |
| 18193 | 18202 | const tracy = trace(@src()); |
| 18194 | 18203 | defer tracy.end(); |
| 18195 | 18204 | |
| 18205 | if (block.inlining == null and sema.func_is_naked) { |
| 18206 | assert(!block.is_comptime); |
| 18207 | if (block.wantSafety()) { |
| 18208 | // Calling a safety function from a naked function would not be legal. |
| 18209 | _ = try block.addNoOp(.trap); |
| 18210 | } else { |
| 18211 | try block.addUnreachable(false); |
| 18212 | } |
| 18213 | return always_noreturn; |
| 18214 | } |
| 18215 | |
| 18196 | 18216 | const mod = sema.mod; |
| 18197 | 18217 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 18198 | 18218 | const operand = try sema.resolveInst(inst_data.operand); |
| 18199 | | |
| 18200 | 18219 | const r_brace_src = inst_data.src(); |
| 18201 | 18220 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 18202 | 18221 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); |
| ... | ... | @@ -18222,7 +18241,7 @@ fn zirRetImplicit( |
| 18222 | 18241 | return sema.failWithOwnedErrorMsg(msg); |
| 18223 | 18242 | } |
| 18224 | 18243 | |
| 18225 | | return sema.analyzeRet(block, operand, .unneeded); |
| 18244 | return sema.analyzeRet(block, operand, r_brace_src); |
| 18226 | 18245 | } |
| 18227 | 18246 | |
| 18228 | 18247 | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | ... | @@ -18244,7 +18263,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 18244 | 18263 | const src = inst_data.src(); |
| 18245 | 18264 | const ret_ptr = try sema.resolveInst(inst_data.operand); |
| 18246 | 18265 | |
| 18247 | | if (block.is_comptime or block.inlining != null) { |
| 18266 | if (block.is_comptime or block.inlining != null or sema.func_is_naked) { |
| 18248 | 18267 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); |
| 18249 | 18268 | return sema.analyzeRet(block, operand, src); |
| 18250 | 18269 | } |
| ... | ... | @@ -18450,6 +18469,8 @@ fn analyzeRet( |
| 18450 | 18469 | return always_noreturn; |
| 18451 | 18470 | } else if (block.is_comptime) { |
| 18452 | 18471 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); |
| 18472 | } else if (sema.func_is_naked) { |
| 18473 | return sema.fail(block, src, "cannot return from naked function", .{}); |
| 18453 | 18474 | } |
| 18454 | 18475 | |
| 18455 | 18476 | try sema.resolveTypeLayout(sema.fn_ret_ty); |
| ... | ... | @@ -33571,6 +33592,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33571 | 33592 | .owner_decl = decl, |
| 33572 | 33593 | .owner_decl_index = decl_index, |
| 33573 | 33594 | .func_index = .none, |
| 33595 | .func_is_naked = false, |
| 33574 | 33596 | .fn_ret_ty = Type.void, |
| 33575 | 33597 | .fn_ret_ty_ies = null, |
| 33576 | 33598 | .owner_func_index = .none, |
| ... | ... | @@ -33622,6 +33644,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33622 | 33644 | .owner_decl = decl, |
| 33623 | 33645 | .owner_decl_index = decl_index, |
| 33624 | 33646 | .func_index = .none, |
| 33647 | .func_is_naked = false, |
| 33625 | 33648 | .fn_ret_ty = Type.void, |
| 33626 | 33649 | .fn_ret_ty_ies = null, |
| 33627 | 33650 | .owner_func_index = .none, |
| ... | ... | @@ -34405,6 +34428,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 34405 | 34428 | .owner_decl = decl, |
| 34406 | 34429 | .owner_decl_index = decl_index, |
| 34407 | 34430 | .func_index = .none, |
| 34431 | .func_is_naked = false, |
| 34408 | 34432 | .fn_ret_ty = Type.void, |
| 34409 | 34433 | .fn_ret_ty_ies = null, |
| 34410 | 34434 | .owner_func_index = .none, |
| ... | ... | @@ -34748,6 +34772,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 34748 | 34772 | .owner_decl = decl, |
| 34749 | 34773 | .owner_decl_index = decl_index, |
| 34750 | 34774 | .func_index = .none, |
| 34775 | .func_is_naked = false, |
| 34751 | 34776 | .fn_ret_ty = Type.void, |
| 34752 | 34777 | .fn_ret_ty_ies = null, |
| 34753 | 34778 | .owner_func_index = .none, |