Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unable to @ptrCast const callconv(.Naked) function to call it #4204

Closed
andrewrk opened this issue Jan 16, 2020 · 2 comments
Closed

unable to @ptrCast const callconv(.Naked) function to call it #4204

andrewrk opened this issue Jan 16, 2020 · 2 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@andrewrk
Copy link
Member

test "call naked function" {
    const S = struct {
        fn foo() callconv(.Naked) void {}
    };
    const f = @ptrCast(fn (x: i32) callconv(.C) void, S.foo);
    f(10);
}

gives

./test2.zig:6:5: error: unable to call function with naked calling convention
    f(10);
    ^

Can be worked around by changing const f to var f but that should not be necessary.

The fix should be as simple as:

diff --git a/src/codegen.cpp b/src/codegen.cpp
index 95b55675b..a04815bfc 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4022,7 +4022,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
     bool callee_is_async;
     if (instruction->fn_entry) {
         fn_val = fn_llvm_value(g, instruction->fn_entry);
-        fn_type = instruction->fn_entry->type_entry;
+        fn_type = instruction->fn_ref ?
+            instruction->fn_ref->value->type : instruction->fn_entry->type_entry;
         callee_is_async = fn_is_async(instruction->fn_entry);
     } else {
         assert(instruction->fn_ref);
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);

However this is revealing other bugs.

@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Jan 16, 2020
@andrewrk andrewrk added this to the 0.7.0 milestone Jan 16, 2020
@mlarouche
Copy link
Sponsor Contributor

Example of usage: https://godbolt.org/z/a5HMg7

@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Aug 13, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
@Vexu
Copy link
Member

Vexu commented Dec 28, 2022

Likely duplicate of #2626, works at runtime now.

@Vexu Vexu closed this as completed Dec 28, 2022
@andrewrk andrewrk modified the milestones: 0.12.0, 0.11.0 Dec 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

3 participants