[LLVMdev] Darwin vs exceptions
Dale Johannesen
dalej at apple.com
Sun Dec 9 10:13:45 PST 2007
(Mail system seems to have eaten this, sorry if it's a repeat)
On Dec 8, 2007, at 12:48 AM, Duncan Sands wrote:
> Hi Dale,
>
>> - Why was C++ claiming that every selector has a catch-all handler?
>
> this is easy: because the semantics of invoke require it. Yes,
> really.
> If unwinding reaches an invoke then control is required to jump to the
> unwind basic block. At first I thought this probably wouldn't
> matter -
> that it would be OK to not jump to the landing pad if the exception
> was
> not being caught by it - and didn't implement it, but several eh
> failures
> in the LLVM testsuite could be tracked down to it: the optimizers
> really
> do exploit this property of invoke - it is quite subtle. You
> typically see
> it when code is massively inlined into one big flat main function.
> Then I
> tried to implement it by pushing a "cleanup" at the end of the
> exception
> list. But the unwinder treats cleanups specially, and ignores them
> if during
> unwinding it only sees cleanups all the way up to the top - in
> short there
> were testsuite failures with this approach. So the only thing to
> do was
> to push a catch-all on to the end of the list.
OK, playing around with the testsuite it appears there's a bug in
llvm's inliner with EH, which is probably what's causing the effect
you're talking about. Suppose we have
#include <cstdio>
class A {
public:
A() {}
~A() {}
};
void f() {
A a;
throw 5.0;
}
main() {
try {
f();
} catch(...) { printf("caught\n"); }
}
The IR for f correctly has the throw call reaching the landing pad,
which cleans up 'a' and then calls Unwind_Resume. Inlining g into f
naively copies this structure which is wrong; we do not want to call
Unwind_Resume in this case because there is a real handler in the
same function. See the code produced by gcc -O3. I think what you
did is make this incorrect Unwind_Resume work (on your OS), but
that's not the right way to fix this.
>> The documentation above just says
>> the C++ personality function will terminate the program if it detects
>> that unwinding the exception only results in matches with cleanups.
>> Isn't that what's supposed to happen if there's no handler anywhere?
>
> It is, and it is what will happen: with the current code you will
> unwind
> into each landing pad and be rethrown until you get to the top.
> Then the
> program will be terminated. Yes, this means that you get
> terminated slightly
> more slowly than with gcc, however I don't see how to obtain
> correct invoke
> semantics (and thus: correctly working programs) without it.
>
>> - What is the right thing for Linux? Is the deletion above safe
>> there?
>
> No, and it's not safe anywhere else either, though most of the time it
> doesn't make any difference.
>
> Ciao,
>
> Duncan.
More information about the llvm-dev
mailing list