Description
When running code compiled to WebAssembly, invoking a function pointer via an incompatible signature will cause a trap, e.g.:
RuntimeError: null function or function signature mismatch
LLVM supports two command line diagnostics to capture warning/error messages with respect to unsafe function pointer signature casts: -Wbad-function-cast
and -Wcast-function-type
to help detect such errors at compile-time.
However, these diagnostic flags are not designed to be accurate with respect to WebAssembly function dispatch signature rules. For example, the following program
void foo(int x) { }
int main()
{
reinterpret_cast<void(*)(unsigned int)>(foo)(0); // (A)
reinterpret_cast<void(*)(float)>(foo)(0.f); // (B)
return 0;
}
will pass line A, but crash on line B when run in WebAssembly.
If the program is built with -Wbad-function-cast
, maybe surprisingly, no diagnostic will be given. If the program is built with -Wcast-function-type
, a diagnostic will be given of both lines A and B, which can be counterproductive and overwhelming.
In WebAssembly, the function pointer call signature checks are performed with respect to only the primitive types that Wasm recognizes: i32
, i64
, f32
, f64
and v128
. Hence under those rules, line A above is ok, but line B above is not.
In our scenario, when working on the Unity3D engine codebase, on the order of ~millions of code lines, enabling -Wcast-function-type
will produce thousands of lines of diagnostics, of which most (all?) are false positives. Whereas enabling -Wbad-function-cast
does not report a single diagnostic warning.
It would be extremely helpful to have a command line flag, which would only diagnose those function signature casts that precisely will violate the WebAssembly signature check rules, i.e. casts between the Wasm primitive types, and nothing else.
With such a flag, it would be more feasible to audit through our millions of lines of code, to focus on call sites that will be known at compile time to run into trouble. Would it be possible to add such a -Wbad-wasm-function-cast
flag for example?