why does clang not support builtin_apply?

6.5 Constructing Function Calls

Using the built-in functions described below, you can record the arguments a function received, and call another function with the same arguments, without knowing the number or types of the arguments.

You can also record the return value of that function call, and later return that value, without knowing what data type the function tried to return (as long as your caller expects that data type).

However, these built-in functions may interact badly with some sophisticated features or other extensions of the language. It is, therefore, not recommended to use them outside very simple functions acting as mere forwarders for their arguments.

— Built-in Function: void * __builtin_apply_args ()

This built-in function returns a pointer to data describing how to perform a call with the same arguments as are passed to the current function.

The function saves the arg pointer register, structure value address, and all registers that might be used to pass arguments to a function into a block of memory allocated on the stack. Then it returns the address of that block.

— Built-in Function: void * __builtin_apply (()())

__builtin_apply is an abomination. Even in GCC it is held to have been a bad idea.


Interesting. Just having __builtin_apply_args() (and a correspoding __builtin_apply_args_size()), would make it possible to do a memcpy store of arguments to a (varargs) function, which sometimes is useful for our users (for debug/trace purposes).

/Patrik Hägglund

I think varargs functions would be an example of where this builtin would not work.


Indeed. However, I wouldn't have called variable number of arguments a "sophisticated feature". :slight_smile:

/Patrik Hägglund

I would also like so tee support for __builtin_apply*. We use it in macros and such.
If others are interested, please speak up.

The __builtin_va_arg_pack() and __builtin_va_arg_pack_len() builtins are useful in this context and, unlike __builtin_apply(), are possible to implement correctly in the general case. I believe that some GNU system headers use them when they are available, so they are probably worth supporting.

I'd love to see __builtin_apply() implemented and working properly too, but on most architectures / ABIs it's possible to implement it in such a way that it works except for some corner cases and on others it's impossible to implement correctly at all. Code that uses it is either non-portable or just plain broken currently, and that's not something I'd like to see clang encourage.


I don’t think we’d say “no” to a (well implemented) version of this, so long as it is localized and doesn’t cause widespread increase in complexity in the compiler. Specifically, I wouldn’t want to see an IR change to support it.