[all-commits] [llvm/llvm-project] 6a8666: [WebAssembly] Ignore filters in Emscripten EH land...
Heejin Ahn via All-commits
all-commits at lists.llvm.org
Fri Jun 4 20:35:36 PDT 2021
Branch: refs/heads/release/12.x
Home: https://github.com/llvm/llvm-project
Commit: 6a86669a6d99179997feaa015b92423cba64ad96
https://github.com/llvm/llvm-project/commit/6a86669a6d99179997feaa015b92423cba64ad96
Author: Heejin Ahn <aheejin at gmail.com>
Date: 2021-06-04 (Fri, 04 Jun 2021)
Changed paths:
M llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
M llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
Log Message:
-----------
[WebAssembly] Ignore filters in Emscripten EH landingpads
We have been handling filters and landingpads incorrectly all along. We
pass clauses' (catches') types to `__cxa_find_matching_catch` in JS glue
code, which returns the thrown pointer and sets the selector using
`setTempRet0()`.
We apparently have been doing the same for filters' (exception specs')
types; we pass them to `__cxa_find_matching_catch` just the same way as
clauses. And `__cxa_find_matching_catch` treats all given types as
clauses. So it is a little surprising; maybe we intended to do something
from the JS side and didn't end up doing?
So anyway, I don't think supporting exception specs in Emscripten EH is
a priority, but this can actually cause incorrect results for normal
catches when functions are inlined and the inlined spec type has a
parent-child relationship with the catch's type.
---
The below is an example of a bug that can happen when inlining and class
hierarchy is mixed. If you are busy you can skip this part:
```
struct A {};
struct B : A {};
void bar() throw (B) { throw B(); }
void foo() {
try {
bar();
} catch (A &) {
fputs ("Expected result\n", stdout);
}
}
```
In the unoptimized code, `bar`'s landingpad will have a filter for `B`
and `foo`'s landingpad will have a clause for `A`. But when `bar` is
inlined into `foo`, `foo`'s landingpad has both a filter for `B` and a
clause for `A`, and it passes the both types to
`__cxa_find_matching_catch`:
```
__cxa_find_matching_catch(typeinfo for B, typeinfo for A)
```
`__cxa_find_matching_catch` thinks both are clauses, and looks at the
first type `B`, which belongs to a filter. And the thrown type is `B`,
so it thinks the first type `B` is caught. But this makes it return an
incorrect selector, because it is supposed to catch the exception using
the second type `A`, which is a parent of `B`. As a result, the `foo` in
the example program above does not print "Expected result" but just
throws the exception to the caller. (This wouldn't have happened if `A`
and `B` are completely disjoint types, such as `float` and `int`)
Fixes https://bugs.llvm.org/show_bug.cgi?id=50357.
Reviewed By: dschuff, kripken
Differential Revision: https://reviews.llvm.org/D102795
(cherry picked from commit 412a3381f721452fb6cd33bc30e7700102639e3f)
More information about the All-commits
mailing list