[clang] [clang][WebAssembly] Handle casted function pointers with different number of arguments (PR #153168)

Jorge Zapata via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 16 12:09:33 PDT 2025


turran wrote:

> 
> Let me refine what I meant here a little bit. The key problem I have with your proposed approach is that it redefines the semantics of the language in a subtle and hard-to-understand way (i.e. compile-time vs runtime casts, as mentioned [above](https://github.com/llvm/llvm-project/pull/153168#pullrequestreview-3122024433)). I think that this isn't going to be very "transparent to the programmer" if you have a flag that just changes this behavior across the program, it could have effects outside of the very-specially-designated intended uses.
>

I agree, but as I already commented, finding a middle ground, even if desirable, is sometimes impossible.
 
> I agree with the statement above that changing the indirect call behavior is better than changing the casting behavior because it's much easier to understand and more predictable. It's also why I'm wondering if we can localize the effect to specific callsites which can mitigate both any increased cost for the calls, and any potentially-surprising behavior changes.

The cost is unavoidable if the developer wants the webassembly ABI to work like other ABIs, where you simply pass fewer arguments than the ones expected, and don't change their own code. The proposed approach mimics such behavior; indeed, some collateral potential problems might occur, but that's the purpose of having an optional flag and knowing the implications.

> The example you've given have centralized macros such as `FUNCTION_POINTER` and typedefs for the various types involved. If we can, for example, define the macro such that the calls can call a compiler builtin to make the dispatch call, then we could localize any extra runtime costs. Or, if we could use the typedef to designate the pointer types in a special way, we could do something similar (this is what I was speculating about with the addrspace thing).

Yes, my examples have such a macro to be explicit about usage. But in the end, you can have a common macro like my example or a manual cast of the target function to the desired type in many ways and forms, which makes your approach developer-related, as they will have to know how to cast to make their cast to work. Maybe we can make the flag to be more explicit about the potential consequences?

>The point is that the special calls or casts could be explicit rather than implicit. It's true that this isn't completely transparent in that it would require no source changes at all, but I think it's pretty reasonable, and I would hope that the GLib code is organized in such a way that only the special signal dispatch code needs this behavior, and it might therefore be acceptable to take some macro changes.

We already tried some alternatives to avoid this problem (intermediate functions, different casts, adding missing parameters, etc), but those weren't accepted. In fact, there is a [hard requirement](https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md?ref_type=heads#calling-functions-through-differently-typed-function-pointers) in their documentation. This is mandatory at the compiler level. Nevertheless, there is a misunderstanding in the documentation about the `EMULATE_FUNCTION_POINTER_CASTS` as it has nothing to do with the number of arguments, only with the _type_ of arguments.

The signals are not the problem; is the whole GOBject inheritance model that is based on this ABI assumption.  It is difficult for me to find a middle ground here ...

https://github.com/llvm/llvm-project/pull/153168


More information about the cfe-commits mailing list