[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