Notes about __cxa_end_catch

Christophe de Dinechin ddd at cup.hp.com
Fri Dec 17 02:29:40 UTC 1999


Coleen Phillimore wrote:
> 
> /*
> Regarding the discussion of __cxa_end_catch:
> 
> If you need to clean up more than one live exception from a
> catch handler, don't you need a 'count' parameter to
> __cxa_end_catch?  In this case, you destroy both X and
> Y objects (whether or not they're both on the stack,
> or just X is).
> 
> Our equivalent of end_catch has a count parameter which
> is set to the number of live exception objects to
> delete and is used for branching out of the nested catch
> clause (not by rethrow).
> */
> struct X { X(); ~X(); };
> struct Y { Y(); ~Y(); };
> extern "C" int printf(const char *,...);
> main()
> {
>   try {
>     throw X();
>   } catch (X x) {
>     try {
>         throw Y();
>     } catch(...) {
>         //generates __cxa_end_catch(/*levels=*/2)
>         return 1;
>     }
>   }
> }
> 

Two __cxa_end_catch calls need to be generated here, since you are closing two
catch clauses. Thus, the code for the above will look like:


main:
	X *thrown = __allocate_exception(sizeof(X));
	__throw(thrown);	// Landing pad LP1

LP1:
	// Pushes the X on the caught stack
	X* xptr = __begin_catch(exc)
	Y *thrown = __allocate_exception(sizeof(Y));
	__throw(thrown);	// Landing pad LP2

LP2:
	// Pushes the Y on the exception stack
	return_value = 1;
	goto exiting_inner_catch;

exiting_inner_catch:
	// Pops Y off the stack, delete it
	__end_catch();
	goto exiting_outer_catch;

exiting_outer_catch:
	// Pops X off the stack, delete it
	__end_catch();
	goto return_point;

return_point:
	...

This is very similar to what you need to do for locals in each of the catch
blocks anyway. I am against having an extra argument, because it would be quite
detrimental in the general case (where you close only one catch clause).


Christophe




More information about the cxx-abi-dev mailing list