| Issue |
114600
|
| Summary |
WASM rethrow instruction is generated with a wrong index
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
purplesyringa
|
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.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs