Skip to content

support va_start and va_end #633

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

Open
folkertdev opened this issue Feb 15, 2025 · 3 comments
Open

support va_start and va_end #633

folkertdev opened this issue Feb 15, 2025 · 3 comments

Comments

@folkertdev
Copy link
Contributor

Mostly this is just an infodump, because I'm not sure how to fix this one.

The tests/ui/delegation/fn-header.rs test fails because these two functions are not implemented.

fn va_start(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> {
    unimplemented!();
}
 
fn va_end(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> {
    unimplemented!();
}

It's slightly surprising to me that this is the only test that fails for that reason. There are plenty of other tests that also use C varargs, and they apparently don't cause issues (and don't hit these functions). The test does use incomplete features (fn_delegation), but I don't immediately see why that is relevant. I think these functions should just work.

Anyway, implementing them appears straightforward (the llvm backend does something similar).

fn va_start(&mut self, va_list: RValue<'gcc>) -> RValue<'gcc> {
    let func = self.context.get_builtin_function("__builtin_va_start");
    self.context.new_call(self.location, func, &[va_list])
}

fn va_end(&mut self, va_list: RValue<'gcc>) -> RValue<'gcc> {
    let func = self.context.get_builtin_function("__builtin_va_end");
    self.context.new_call(self.location, func, &[va_list])
}

However, this still fails because

thread 'rustc' panicked at /home/folkertdev/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gccjit-2.5.0/src/context.rs:1131:17:
unimplemented primitive type for builtin (type: BT_VALIST_REF)

which I believe is because BT_VALIST_REF (and likely also BT_VALIST_ARG) are unimplemented:

    case BT_CONST_STRING: return m_ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR);
    // case BT_DFLOAT32:
    // case BT_DFLOAT64:
    // case BT_DFLOAT128:
    // case BT_VALIST_REF:
    // case BT_VALIST_ARG:
    case BT_I1: return m_ctxt->get_int_type (1, true);
    case BT_I2: return m_ctxt->get_int_type (2, true);

https://github.com/rust-lang/gcc/blob/48664a6cab29d48138ffa004b7978d52ef73e3ac/gcc/jit/jit-builtins.cc#L542-L543

That's where my knowledge stops. An LLM suggested that a void pointer might work, but I have no idea whether that is accurate (or how to even evaluate whether that is in fact correct).

@bjorn3
Copy link
Member

bjorn3 commented Feb 15, 2025

va_start/va_end are necessary for defining variadic functions in Rust. For declaring variadic functions defined in C, they are not used. The tests/ui/abi/variadic-ffi.rs test should also fail with cg_gcc though. You probably didn't see the failure because of

disabling all abi tests.

@tahadostifam
Copy link

I'm happy to see such an issue at this repository! Because I have a similar problem in my hobby programming language (Cyrus) and I tried to get builtin va_arg and va_list and it seems that they're not implemented yet. I sent an email for David Malcolm, The maintainer of gccjit to ask help. He told me dear @antoyo is experienced in this topic.

Is there a solution for this issue?

@antoyo
Copy link
Contributor

antoyo commented Mar 14, 2025

This is not yet supported in gccjit. As mentioned above, you would at least need to add support for BT_VALIST_REF.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants