diff --git a/src/codegen.cpp b/src/codegen.cpp index 95b55675b..36e2ac654 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4020,15 +4020,22 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr LLVMValueRef fn_val; ZigType *fn_type; bool callee_is_async; + CallingConvention cc; if (instruction->fn_entry) { fn_val = fn_llvm_value(g, instruction->fn_entry); fn_type = instruction->fn_entry->type_entry; callee_is_async = fn_is_async(instruction->fn_entry); + if (instruction->fn_ref != nullptr) { + cc = instruction->fn_ref->value->type->data.fn.fn_type_id.cc; + } else { + cc = fn_type->data.fn.fn_type_id.cc; + } } else { assert(instruction->fn_ref); fn_val = ir_llvm_value(g, instruction->fn_ref); fn_type = instruction->fn_ref->value->type; - callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; + cc = fn_type->data.fn.fn_type_id.cc; + callee_is_async = cc == CallingConventionAsync; } FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; @@ -4036,8 +4043,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr ZigType *src_return_type = fn_type_id->return_type; bool ret_has_bits = type_has_bits(src_return_type); - CallingConvention cc = fn_type->data.fn.fn_type_id.cc; - bool first_arg_ret = ret_has_bits && want_first_arg_sret(g, fn_type_id); bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type); bool is_var_args = fn_type_id->is_var_args; diff --git a/src/ir.cpp b/src/ir.cpp index d871aa27a..ffc6aa24c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -18848,7 +18848,7 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC return ira->codegen->invalid_instruction; } else if (fn_ref->value->type->id == ZigTypeIdFn) { ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); - ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; + ZigType *fn_type = fn_ref->value->type; CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, fn_ref, nullptr, modifier); diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index 13859b92c..e8c07480e 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -272,3 +272,11 @@ test "ability to give comptime types and non comptime types to same parameter" { S.doTheTest(); comptime S.doTheTest(); } + +test "call naked function" { + const S = struct { + fn foo() callconv(.Naked) void {} + }; + const f = @ptrCast(fn () callconv(.C) void, S.foo); + f(); +}