<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/114600>114600</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
WASM rethrow instruction is generated with a wrong index
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
purplesyringa
</td>
</tr>
</table>
<pre>
This is a wasm target, built with `-fwasm-exceptions`. Reproducer:
```cpp
#include <cstdio>
__attribute__((noinline)) void print_current() noexcept {
try {
throw;
} catch (int x) {
printf("%d\n", x);
}
}
struct Dropper {
~Dropper() {
try {
throw 1;
} catch (...) {
print_current();
}
}
};
int main() {
try {
Dropper dropper;
throw 2;
} catch (...) {
print_current();
}
}
```
Expected output: `1 2`, actual output: `1 1`.
(I'm using `emcc -O2 -fwasm-exceptions test.cpp` for testing if that's important.)
The problem is in the codegen for `main`:
<details><summary>Wasm IR</summary>
```
(func (;6;) (type 11) (result i32)
(local i32 i32)
global.get 0
local.set 1
call 22
local.tee 0
i32.const 2
i32.store
try ;; label = @1
local.get 0
call 28
catch_all
local.get 1
global.set 0
call 22
local.tee 0
i32.const 1
i32.store
try ;; label = @2
try ;; label = @3
local.get 0
call 28
catch 0
local.set 0
local.get 1
global.set 0
local.get 0
call 29
drop
call 5
call 30
try ;; label = @4
try ;; label = @5
rethrow 2 (;@3;)
catch 0
local.set 0
local.get 1
global.set 0
local.get 0
call 29
drop
call 5
try ;; label = @6
call 30
delegate 5
i32.const 0
return
end
unreachable
delegate 3
unreachable
end
catch_all
local.get 1
global.set 0
call 37
unreachable
end
unreachable
end
unreachable
)
```
</details>
In pseudocode, simplified:
```
try:
throw(2)
catch_all:
try:
try:
throw(1)
catch:
print_current()
rethrow(0)
catch:
print_current()
```
So `rethrow(0)` rethrows the same exception as has just been handled, so the same exception object is caught twice. `rethrow(1)` would work correctly. The current behavior leads to all sorts of memory corruption and hard-to-debug state.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUV8tu47gS_Rp6U4hAUX4uvEicDtCLiwt0N9DLgKLKFnsoUiBLcbKZbx9Qlq1H5GAGCBSrWK9zWMWiZAj6ZBH3bPXEVs8L2VDp_L5ufG0wfHhtT3KRu-Jj_6vUAXQACWcZKiDpT0hMHCBvtCE4ayqBrfnDMS4_4LvCmrSzga15Aj-w9q5oFHqWPTL-zPj1ueaXP1XXnURk2irTFAgsO6hAhXYs-zY0en2VRF7nDeHrKxNbJrbWaWu0RSZ2TOzgzekCaq8tvarGe7TUqu3AuktmwDZPF2dA_mPwBgBUendm2U3CNs-gJKkSmNhqS_AePY1M2lDHNoZgYlWw1cG2Pw-tcu-MbZ47JLcf7TOQbxTBs3d1jX7o_O9O1gEYZzpNvUse0kH6EwBJknzyA3NcTV3MIbiqXJ6Rm0pq-znVT4legRYduGzKP4h7OzAH4Mv0Zzi_Vt0w-2_vNSrCAlxDdUMse4z1nIKIeuIAUlEjzXQ1jfU9qmix_c7EpoImaHuKSlgpBQ__F_CpN4AwUBJLf83h6Hz7Hq30EaiUxMQmgK5q50lairCHkX6VCLV3ucEqNqa2QCWCcgWe0Lbu2Jq3-7Hm07bLDgWS1CbE1soOoakq6T9Y9u13bO7vP1h2YOKlF8_zJrbHxqq4KSx7WkfG48aILX3UCGnavXkMjSHQmbgBgCg3TkkTxZOlk3G5NMkJCfhV1uomAQnSq0hJY0CIsQYh9kY6E4lyNhCIoSiQ8ziqzOyJZU9gZI4GWPYMbMnTvrgunkfpXKNv-2RIla_SmDmzga8OW5hzJqa2IzBDOOlYOAJ0H5IYnRN3lLJOaRb0DPCLKLbmRK_fsdmFCS_3uZnfgUsWu7FaPExmkl3NyDI-PP1neFiOje4TtpoqAnjsjrCuM1pa2-aY6s4yN8_eXdq-pu4_0DdP4T0av-Jk_Vl1yvswJho8ScJbhL7QZ7Q9UuPtVI626ESN9ShVKXODk-q4hsnG8jsGvceZ3r5bxfc24gJ-81WOfcD5pL6A2A-GyQHdnuKDk34wAr5bqAM2hYsDI863oKva6KPG4t4d7fJKcSA8Tq9LYtsf4T1hI72h3dTJraI6Z-mnZmmd9jZzE_9eIzKx5aP1f-tr9p7w08W5OnG95tdgoZ3CQVYIt0EPMkApA_xpAkGOaKGUtjBYtLy7OQuX_0FFca4r2ZxKAjprhck4dNqFPrvGFHB2_i9QzntUZD4SiPeDDhTkWMo37TwYlEUAchALMjhPAdwRKqyc_2iNmy5jW0ApffFA7qHAvDlBIEmYLIp9VuyynVzgPt1kfLkTy-VqUe45CuQ536xFtsm3XKjNiq93-SZbKZ7JNV_oveBimaY8FVzw5TLJZK6OUiHu1ul2WeRsybGS2iTGvFWJ86eFDqHBfZou15wv2hMmtB8qQlg8Q7sab9mr54XfR6OHvDkFtuRGBwq9G9JkcP_78ef_bkeztpcbd4SqA5zQopfx8td-x0g4exevYbbA90Xjzb4kqkOsGPHCxMtJU9nkiXIVEy8xTPfvofYubhsTL21ygYmXLvu3vfgnAAD__79nrQU">