[LLVMdev] assumptions about varargs ABI

Jay Foad
Thu, 13 Sep 2007 21:07:38 -0000

Hi,

Various parts of LLVM seem to assume that the ABI for a varargs
function is compatible with the ABI for a non-varargs function, so
that code like this:

define void @f(i32 %x) {
    ...
}
...
    call void (...)* bitcast (void (i32)* @f to void (...)*)(i32 42)

will work.

(I don't think C guarantees that this will work, at least not in the
version of the C99 standard I checked.)

I'm trying to target a (proprietary) ABI where the ABI is rather
different for varargs and non-varargs functions.

The particular bit of llvm-gcc that is causing me trouble at the
moment is TreeToLLVM::StartFunctionBody():

  // If the function has no arguments and is varargs (...), turn it into a
  // non-varargs function by scanning the param list for the function.  This
  // allows C functions declared as "T foo() {}" to be treated like
  // "T foo(void) {}" and allows us to handle functions with
K&R-style
  // definitions correctly.

This gives rise to cases where functions are being called as if they
had varargs, but this optimisation has kicked in so the function is
defined without varargs.

Would it be reasonable to do the same optimisation at a call? That is,
given some code that calls a function declared with no prototype:

    void f();
    ...
    f(42);

to bitcast the callee into a function type based on what the actual
arguments being passed in are, as if the source had been:

  ((void (*)(int))&f)(42);

?

Jay.