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

Reply via email to