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

    <tr>
        <th>Summary</th>
        <td>
            Bitcasts from extern symbols to function pointers produce corrupted WebAssembly binary
        </td>
    </tr>

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

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

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

<pre>
    Original issue in https://github.com/emscripten-core/emscripten/issues/15722 / https://github.com/rust-lang/rust/issues/91628.

The minimal repro for C/C++ looks like this:

```c
extern char maybe_func;

int main() {
    int(*func)() = (int(*)())&maybe_func;
    return func();
}
```

This produces the following LLVM IR with `-target wasm32-unknown-emscripten` (but likely reproducible with other Wasm targets too):

```llvm
@maybe_func = external local_unnamed_addr global i8, align 1

define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr #0 {
  %3 = tail call noundef i32 @maybe_func()
  ret i32 %3
}

attributes #0 = { mustprogress norecurse "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" }
```

The Wasm generated by LLVM is corrupted, and `wasm-opt`, `wasm-validate` etc fail:

```bash
$ emcc temp.c -O -Wl,--allow-undefined
[parse exception: attempted pop from empty stack / beyond block start boundary at 262 (at 0:262)]
Fatal: error in parsing input
emcc: error: '/home/rreverser/emsdk/upstream/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers a.out.wasm -o a.out.wasm --detect-features' failed (returned 1)
```

As discussed in linked issues, this is likely due to `maybe_func` being called directly without bitcast handling that Wasm function pointers require.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyEVk2P2zwO_jXKhVDgyImTHHKYDwRY4F28QLHYHgeyxNjqyJKXomaa_vqFbDfNFLNdIHBs6SHFj4ekdEquC4gnsXsUu-eVztxHOn35gm9ICWnVRns9_U2uc0F7cCllBBegZx6TqB-EOgt17hz3uV2bOAh1xiEZciNjkCYSflgR6jypSEKdN7u9UiDU-U_KKCeWXodueb9XcNw06rAW1bOoHubnv3qEwQU3aA-EI0W4RIInoc5PQj0K9Qg-xtcE3r0icO-mQ-_kRVPNPzN_43dGCmB6TTDoa4svlxyMqB_vhVxgGLQLQh2EOoLYL7sAAC7wtPwwyanjT0z9DEIdbru3nenXfHJUUUbImQLMqib0zZD9828OfIyKSzBStNlgAu4RLtH7-O5CB3_99e9_wj--wLvjHkRTSdbUIcO7TkOtZA6vIb4HeZfBpiqmt5mnKPrrHGibjWs9znoi90jwVacBZnUJOMbJ4M_D7f3bsCxtq1_eT3Gac6A9-Gi0f8kh6AHti7aWoPOxLaw8CPUE2rsuwOb-AIsXFxB6Zy0GCDEHixdwtQKxrV5eStZeNHWmPN5KQmp1Qwm1q4rakQlCNHrkTHjbJdQ2xIAFtikp_cQ6oerqng5C7erJJdbOg9He_27SXeLnBC-ShDxD1K7-PePTUzOTazNjWk4tBNs_wpATjxQ7wpQgREKTKRWj1YX0gHKMLjCSUErUz0Kp4pKYqlINLkiPnfbyDQ1Hku_Ocn9DVgssRMmkx9GFTg76DsCUf6pKrM2rHCnyrKnNlwuSTO4H3uCHBTsTRpox37Y6DEjOTID_Q3ScWTdJaEYL7XWmuEtgIlEeGe1ElmAL3QvNZRy5KFJPt5U37Z3VjIXsyAYu2vn_xd1Wp35ZUlvAwRhgHMa1Afk3yK9eqCcpdak3OeXaBbQLfvc46pIO_G5wZBeDqB9AcxEvto9xhAvFAcr3FaYoTv2yxWsMFlofzWtZJoa2EEnTFTSDakokD5qhEvWDalRh0m4J3FmzLr4AEkUqrbzYUFqBC2Pmpe8Nxtww5UWovVDnPg6lnRMtw2Fu7fZVqHMeExPq0rLb0grPUxzvRsGlzA_3A0FKew2F_Em6ZgtSjjolqakT9fPEN_cD5bckJ2JetEGJ38dIjFb26EekBHodM6_LCSDjhy9psXBMXlCXck1C7afkoS0RmRsoWtjcautTHj0ksC6ZnBLaEiHvwmt5WwbP0zQ6CqWWDmgzAsfCnrsCbiposcS1-IoWrCM07K9Ti4yZoXVsdGLodbC-ALnXPPO3KCh8gKU-ExD-JzvC9cqeanusj3qFp02zr5vNfl-pVX86NvsttvX2sNnuLKrq0hz0bn9UG1UbvbG4cidVqbrabOpNvT0otT4YtT9UzdHumtps9lpsKxy08-vSjdeRutXk8Kmpqqpeed2iT9M1QamA73M0So3unld0KjKyzV0S28q7xOmXFnbs8fQ4e5sWRs-DNV2HNvoyHT5xeZlYv-oWvmL7kBIOrb9C64Km6yqTP_3h-jANlvmv9J9vaD7cICbX_hsAAP__Q_HWDA">