[LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?

John McCall rjmccall at apple.com
Mon Jul 12 12:41:44 PDT 2010


On Jul 12, 2010, at 3:00 AM, Yuri wrote:

> On 07/12/2010 00:23, Duncan Sands wrote:
>> IIRC, __cxa_end_catch may throw an exception because it runs the destructor
>> for the exception object, which can execute arbitrary user code and thus may
>> throw an exception.  This is why it is sometimes correct to use invoke for it.
>> However in the case of your example it seems that llvm-gcc didn't optimize the
>> code as well as it might, since the invoke is redundant.
>> 
> 
> But there are cases when the outcomes will be different. In case of gcc 
> frontend terminate() will be called when the original exception's 
> destructor throws an exception and in case of clang 
> Unwind_Resume_or_Rethrow will be called which is different.
> 
> I think one of these cases must be an incorrect behavior.

For your test case, clang++'s code is correct (and better) because
__cxa_end_catch won't throw for a caught exception of that type.  That said,
clang++'s code is incorrect in general, because it actually never emits an invoke for
__cxa_end_catch (and actually marks it nounwind);  I've been assuming a model
where (1) exceptions from destroying an exception temporary triggered a terminate
instead of a normal unwind, which they don't, and (2) the ABI took care of that possibility
for us, which it doesn't, because it can't.

clang++ is also broken in this respect because an exception thrown from
__cxa_end_catch along the unwind path does need to result in a call to std::terminate.

John.



More information about the llvm-dev mailing list