<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/57024>57024</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [WebAssembly+other platforms?] In need of a Clang extension for compile-time validating compatible casting of function pointers
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          juj
      </td>
    </tr>
</table>

<pre>
    In the C/C++ standard, it is unspecified behavior to call a function pointer through a signature that does not match the signature of the function pointed to.

In different x86/ARM ABI, platform-specific and calling convention specific relaxations exist, which make it safe to perform certain types of casts while still being compatible and safe for that specific platform. E.g. calling a function of type `void (int)` through a function signature `void (int, int)` may work, and the second passed argument is safely ignored, or calling a function of type `int (int)` through a function signature `void (int)` may work, and the return value from the function is safely ignored.

In WebAssembly however, in comparison to x86/ARM, due to the security requirements, function pointers are treated more strictly, and neither types of relaxations for function pointers casts will work, but a Wasm VM will throw an exception at runtime.

That is, in Wasm, calling a function of type `int (void)` through a signature `void (void)` will not work, but will raise a function signature mismatch. Also, calling a function of type `void (int)` through a signature `void (int, int)` will not work, but will raise an exception.

However, in Wasm, calling a function `void (char)` through a signature `void (int)` does work, as so also does calling a function `void(int *)` through a signature `void(struct foo *)`.

None of the existing casts (`static_cast`, `dynamic_cast`, `reinterpret_cast` and C cast) accurately capture the "what is safe and works for my target platform" aspects of the function pointer casting.

This raises an interesting portability and future compatibility opportunity. It seems that on all of these target platforms and calling conventions, the rules of what types of casts work and what won't would be well codifiable to a static compile-time check - so maybe Clang front-end could take advantage of this?

I.e. it would be interesting to have a Clang compiler specific extension, something like `__fp_cast<target_sig>(myfunc)`, which would at compile time raise an error if the target compilation platform cannot support the specific signature conversion.

This would have the following benefits:
1. Developers would be able to statically annotate in their codebases where they are intentionally relying on platform specific function pointer conversions, distinguishing from C casts and reinterpret_casts that deal with data. (making such locations searchable)
2. Developers can be more comfortable in targeting their platform specific functionality, while remaining satisfied that the future portability limitations will be caught at compile time, as opposed to developers having to run into silent/cryptic failures or undefined behavior at runtime if the code is attempted to be compiled against a new target platform in the future
3. Developers can use the cast to discover/educate themselves about the exact rules that a target specific function pointer cast allows or does not allow. I.e. "does wasm allow mismatching return type in function pointer casts? what about mismatching pointer types? Well, let me quickly check with a `__fp_cast` utilizing test code)".
4. When LLVM adopts new target platforms in the future, they can piggyback on implementing their custom rules for supported `__fp_cast`s, helping developers identify portability problems in existing code that used such casts.

One of the most common runtime crashes when porting large application codebases to WebAssembly occurs with signature mismatches on function pointers (that were fine on x86). Debugging this in large codebases is painful, because one has to exercise all code paths on WebAssembly at runtime to validate that everything is safe - and typically the people doing the porting haven't written even 0.001% of the code.

It seems that this problem would be solvable by compile time extension to Clang (+ adopting a convention to a codebase), at least for all target/future platforms that are Clang-based, as the compiler would be able to catch fp casts that won't be supported by the target platform.

When I read the documentation page at https://clang.llvm.org/docs/LanguageExtensions.html it seems that such a feature does not exists from before? Would this kind of cast make sense to add?

If one existed, it would probably be possible to enforce a programming convention to always need to use a `__fp_cast` in our Unity3D codebase to improve identifying portability problems to Unity's future platforms.

CC @sunfishcode @kripken @tlively @sbc100
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJylWF1v20gS_DXSy8CCLMmO_aAHR4lxBrK3wGL38hgMyaE08ZDDmw_JvF9_1T0kRVFxsocDNmuJnI-a6urqHmW2aLcvtQgHJXaz1TP-fcR_wgdZF9IVs9VO6CC0F7H2jcp1qVUhMnWQR22dCFbk0hghRRnrPGhbi8bqOii8Ojgb9we88npfyxCdwjMZRGGVF7UNopIhP_DO5xG25AeT1QpstJgtP82WT-n_QFzoslRO1UG8PdwD-dMfv4mnjy8EuDEylNZVNx3iXOAwDFTXe5Hb-ohptPrw3ikj3yQ980K9aR9omdNBA18lXxVR4GWp6LyNcrS2yJULUoO5tsF5gDuXPniaZHCgoMFKptJ-VYOlMzwmGLxOSdwRGQOCHvNCfF7sFwPYEbFEDfYSs_vl0epCzFYP4Ga2esSDEdvD-DOp0xkI6TCxkq04WfdKTwkeh0OBo0I00ntQL90-VsQzREDgTSuwsnWKxYGD_Bwrtvo_oL6L0SmMr8VRmgg6na0udXOFdSqfryp7wvGqDEMO9qSOyiViUryc9lgF4R7ERW-LyBLoOIpOhxZA_h21U8SQpzHTRPAgELOckqTjCligDqfzYNr-PLXSWNKdpTSWI0nles1ObKSynpksBnD6VfpK_Ou39IqoPmELaDpXDa8AzbkI9VfqgpE_SYzadxTQIvTxb0WW4nUV2h9GdDSS4ZEJjNHzQye1Vz8WR6U9e8ZCPBlvfw3wZ2ny97LjlzBH1F7w-Y8LSf2Ez9Hu-UG6_wEnD2QzHXIDordCgpv0_P3t0hpY6unXG2IsBBvzACna85SL4_7T1oN3s3-y8bFGMR2jUU-Czr_RI3wjsPhTtLWsrp46xRpvkOH9G86SHS-IzYXMkXtIJ6RuLpuusgDvanVKMk4mS5OImpRDVSsCrEyFwWoxHpTBgIN_p-443hJnmeQKduD4exIAD1TpyI1FUci0IWOg7cvI6PoSkF7YhobFGp8X4gU1QKnKp3JACQpxJTTQ1wSxf6eQcd6yK0aTHISJmJYmcJFIoZcnW89WH-hvNFTRxUlh59yirmpJxQpGJ0WKGx8Ade2GfEPkB5W_ihvSGpwZM3dGAg5MuA43igDykoEKpyyOsg5y36kDDrN-vnDihVpQdR1QjNkEAvQZZAZphw6FO1dN9RZU7TUdZQc8lcIWGGj0K8v327eySRpa7xKV3yDv2fozRFm1FOyk5XO1TzhAT7eX4BOfk905SEknsXTBSSNlkk0XKDBek234yLFOFaMHfc4wjqDzU_NggSUkfH5WpjXGnuhwmapVqVFs1t3w24X4BLMxtqHKMDDZBzGFEJohSQIUEoc8CYtqR_FWmSQln1CBeKuWCxbFgbXFE1GQWtp7fMThPNdJMxyLhVkkP4jac3C4WO86TZIcpwnf5UKhJIobKqMoZJALMhL0YrSCj4iUsXlXIb2SDt6J41I0mZLVBSUIBhHCtRfRKjlJTWKBY8hiYz7eP52k3O2EYqj_qND9MRrA8NwWM-xkIxzesRsYXenQAT6l5hC4YLlhqrbOycklPHe-YGI4CvXdKTNQxSlIiC8mUj14zl3bULKWUhts76k3i3UBsdTjnv3cAfRCJhGQa8oQVNWkdpvxJVTIhz3O6qm9qNVpakqdmLpDJ_7XV_xHn3RMAeYzaZ9brpDPqog5iRKvK6_MkWw1szF01UTmofM15lf2-_9Ef7SHpHxhDoYLBz-C5ZLnwPxT7aR-iV8M7QUR3LWX3EngfD_cgrwseWmCO54_3ILIgmncV7grRdYAOZhHz5i_Uv1iL2WVy0vHQtWLuEXo_3C84YgcJlL4atW5xWYhvh5ULb58QcMnC9sgdX4QID-JUKoVLYel0ft9m0lgoKa5agw3sud8yKMPSNfEP5XRztEgiglaTvWDMg1NHilWF7Rg2V5kQ-MsEjAhO_cLJEOOcSThc5Yzzxfm-Pu506gss1JVwN5LOnfSH5Kd1bwl1wMiRMimMTqZxsj3oMXxXcBSb-FTRK47T0qqazVwk8PAT-ShlG80jK8Oj5QJWdzvE6eaj5zwnDHgaYMMKyNLJFMwBk9LKOQ7I1RvyuVcg1KNhrfIcGAwY_Cj1MYk3I10kRILL6gdbVN57Bukm3SbapuuPBCnjbIQAXKm08DAIVWirmPAvQfFgVasxXKxXN7OVnd9TAjc5V3rosFhBrron0uVt-bIjpy1l4V3qO90ntQEUD-5-pjknprb0YWee5aeV86VHZFiFDkCyZf4S-kB4-ltesiTZDCu62huaJGis-N0tq7_uKqxOf-UUTZiVL_6BovONyRN1o5bh-HSPyaMU_oFDiTTTbewOd-_uw6Deimsfgih4RZg9UzWT3gXxhyrhXV7PMAkJOTzFzyOmPG559EvDqEy_HvGOSicabgkqCT2wS85M30q2JkCUMVOlro7CiSqcdH3l-mHEo9tUutYFNNWr2RF86Kq_2EpMUmCkCTgjPTmve5oVTU2zakBxIi9k1U1-QGHNjIn2ZLvpbIV-fI4dVLknI1O_EU99_rToBCaANNzKESDT03b-MGqMJbnI6heTKVzEcEd7jGbpY91iZaHsxVfX51uXhFZfAxGH-nyQoOy_Ha5nKvt7f39crl-3Nzfz4vtunhcP8p50MGo7ezu4yjHoX3LPxYMWxPNd5_ES504QDj6fvmcPST9ix6-84bJ71PdbYfWuPK4eXRme6m6PUwyZgssgC8kvu7PDTj7jmsVvmrvoyIl3n1Yrjbzw1Y-fMjvb9eZyh4fHso822Sb2025zO-kyvLNMp8bmSnj6dQodFTNeAl8xiHnertarlbLh-UjWNusNotsKe-L9cO9Wt_KMpcSlFJjZoZcmLstQ4IFe7w0pOjzS-nJ4xWTTOvLGA7Wbb_H73Pedsuw_wtB0XHz">