| ... | @@ -30,6 +30,8 @@ owner_func_index: InternPool.Index, | ... | @@ -30,6 +30,8 @@ owner_func_index: InternPool.Index, |
| 30 | /// an inline or comptime function call. | 30 | /// an inline or comptime function call. |
| 31 | /// This could be `none`, a `func_decl`, or a `func_instance`. | 31 | /// This could be `none`, a `func_decl`, or a `func_instance`. |
| 32 | func_index: InternPool.Index, | 32 | func_index: InternPool.Index, |
| | 33 | /// Whether the type of func_index has a calling convention of `.Naked`. |
| | 34 | func_is_naked: bool, |
| 33 | /// Used to restore the error return trace when returning a non-error from a function. | 35 | /// Used to restore the error return trace when returning a non-error from a function. |
| 34 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, | 36 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, |
| 35 | /// When semantic analysis needs to know the return type of the function whose body | 37 | /// When semantic analysis needs to know the return type of the function whose body |
| ... | @@ -6827,6 +6829,10 @@ fn analyzeCall( | ... | @@ -6827,6 +6829,10 @@ fn analyzeCall( |
| 6827 | var is_inline_call = is_comptime_call or modifier == .always_inline or | 6829 | var is_inline_call = is_comptime_call or modifier == .always_inline or |
| 6828 | func_ty_info.cc == .Inline; | 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 | if (!is_inline_call and is_generic_call) { | 6836 | if (!is_inline_call and is_generic_call) { |
| 6831 | if (sema.instantiateGenericCall( | 6837 | if (sema.instantiateGenericCall( |
| 6832 | block, | 6838 | block, |
| ... | @@ -7509,6 +7515,9 @@ fn instantiateGenericCall( | ... | @@ -7509,6 +7515,9 @@ fn instantiateGenericCall( |
| 7509 | .owner_decl = sema.owner_decl, | 7515 | .owner_decl = sema.owner_decl, |
| 7510 | .owner_decl_index = sema.owner_decl_index, | 7516 | .owner_decl_index = sema.owner_decl_index, |
| 7511 | .func_index = sema.owner_func_index, | 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 | .fn_ret_ty = Type.void, | 7521 | .fn_ret_ty = Type.void, |
| 7513 | .fn_ret_ty_ies = null, | 7522 | .fn_ret_ty_ies = null, |
| 7514 | .owner_func_index = .none, | 7523 | .owner_func_index = .none, |
| ... | @@ -18193,10 +18202,20 @@ fn zirRetImplicit( | ... | @@ -18193,10 +18202,20 @@ fn zirRetImplicit( |
| 18193 | const tracy = trace(@src()); | 18202 | const tracy = trace(@src()); |
| 18194 | defer tracy.end(); | 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 | const mod = sema.mod; | 18216 | const mod = sema.mod; |
| 18197 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; | 18217 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 18198 | const operand = try sema.resolveInst(inst_data.operand); | 18218 | const operand = try sema.resolveInst(inst_data.operand); |
| 18199 | | | |
| 18200 | const r_brace_src = inst_data.src(); | 18219 | const r_brace_src = inst_data.src(); |
| 18201 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 18220 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 18202 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); | 18221 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); |
| ... | @@ -18222,7 +18241,7 @@ fn zirRetImplicit( | ... | @@ -18222,7 +18241,7 @@ fn zirRetImplicit( |
| 18222 | return sema.failWithOwnedErrorMsg(msg); | 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 | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | 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,7 +18263,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 18244 | const src = inst_data.src(); | 18263 | const src = inst_data.src(); |
| 18245 | const ret_ptr = try sema.resolveInst(inst_data.operand); | 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 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); | 18267 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); |
| 18249 | return sema.analyzeRet(block, operand, src); | 18268 | return sema.analyzeRet(block, operand, src); |
| 18250 | } | 18269 | } |
| ... | @@ -18450,6 +18469,8 @@ fn analyzeRet( | ... | @@ -18450,6 +18469,8 @@ fn analyzeRet( |
| 18450 | return always_noreturn; | 18469 | return always_noreturn; |
| 18451 | } else if (block.is_comptime) { | 18470 | } else if (block.is_comptime) { |
| 18452 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); | 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 | try sema.resolveTypeLayout(sema.fn_ret_ty); | 18476 | try sema.resolveTypeLayout(sema.fn_ret_ty); |
| ... | @@ -33571,6 +33592,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi | ... | @@ -33571,6 +33592,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33571 | .owner_decl = decl, | 33592 | .owner_decl = decl, |
| 33572 | .owner_decl_index = decl_index, | 33593 | .owner_decl_index = decl_index, |
| 33573 | .func_index = .none, | 33594 | .func_index = .none, |
| | 33595 | .func_is_naked = false, |
| 33574 | .fn_ret_ty = Type.void, | 33596 | .fn_ret_ty = Type.void, |
| 33575 | .fn_ret_ty_ies = null, | 33597 | .fn_ret_ty_ies = null, |
| 33576 | .owner_func_index = .none, | 33598 | .owner_func_index = .none, |
| ... | @@ -33622,6 +33644,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi | ... | @@ -33622,6 +33644,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33622 | .owner_decl = decl, | 33644 | .owner_decl = decl, |
| 33623 | .owner_decl_index = decl_index, | 33645 | .owner_decl_index = decl_index, |
| 33624 | .func_index = .none, | 33646 | .func_index = .none, |
| | 33647 | .func_is_naked = false, |
| 33625 | .fn_ret_ty = Type.void, | 33648 | .fn_ret_ty = Type.void, |
| 33626 | .fn_ret_ty_ies = null, | 33649 | .fn_ret_ty_ies = null, |
| 33627 | .owner_func_index = .none, | 33650 | .owner_func_index = .none, |
| ... | @@ -34405,6 +34428,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -34405,6 +34428,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 34405 | .owner_decl = decl, | 34428 | .owner_decl = decl, |
| 34406 | .owner_decl_index = decl_index, | 34429 | .owner_decl_index = decl_index, |
| 34407 | .func_index = .none, | 34430 | .func_index = .none, |
| | 34431 | .func_is_naked = false, |
| 34408 | .fn_ret_ty = Type.void, | 34432 | .fn_ret_ty = Type.void, |
| 34409 | .fn_ret_ty_ies = null, | 34433 | .fn_ret_ty_ies = null, |
| 34410 | .owner_func_index = .none, | 34434 | .owner_func_index = .none, |
| ... | @@ -34748,6 +34772,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -34748,6 +34772,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 34748 | .owner_decl = decl, | 34772 | .owner_decl = decl, |
| 34749 | .owner_decl_index = decl_index, | 34773 | .owner_decl_index = decl_index, |
| 34750 | .func_index = .none, | 34774 | .func_index = .none, |
| | 34775 | .func_is_naked = false, |
| 34751 | .fn_ret_ty = Type.void, | 34776 | .fn_ret_ty = Type.void, |
| 34752 | .fn_ret_ty_ies = null, | 34777 | .fn_ret_ty_ies = null, |
| 34753 | .owner_func_index = .none, | 34778 | .owner_func_index = .none, |