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. Yuri
Duncan Sands
2010-Jul-12 10:10 UTC
[LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
Hi Yuri,> 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.since Unwind_Resume_or_Rethrow causes the exception to continue to unwind, the result is also a call to terminate(). Ciao, Duncan.
John McCall
2010-Jul-12 19:41 UTC
[LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
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.
On 07/12/2010 12:41, John McCall wrote:> 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,Which type? There are two pending exceptions at the moment when __cxa_end_catch is called, both with invisible destructors: E* and unknown type thrown from mycatching(). __cxa_end_catch attempts to delete E* and proceed to rethrow the unknown one when the other unknown exception is thrown by E::~E(). Isn't this the condition for terminate()? Yuri
Reasonably Related Threads
- [LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
- [LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
- [LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
- [LLVMdev] clang/g++ frontend: can __cxa_end_catch throw?
- [LLVMdev] Catching C++ exceptions, cleaning up, rethrowing